blob: 74fae04f43ab29f5c2c208475553016b1167ec2c [file] [log] [blame]
Colin Crossd00350c2017-11-17 10:55:38 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross74d1ec02015-04-28 13:30:13 -070015package cc
16
17import (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "os"
Colin Cross74d1ec02015-04-28 13:30:13 -070020 "reflect"
Paul Duffin3cb603e2021-02-19 13:57:10 +000021 "regexp"
Cory Barker9cfcf6d2022-07-22 17:22:02 +000022 "runtime"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070025
Vinh Tran367d89d2023-04-28 11:21:25 -040026 "android/soong/aidl_library"
Colin Crosse1bb5d02019-09-24 14:55:04 -070027 "android/soong/android"
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090028
29 "github.com/google/blueprint"
Colin Cross74d1ec02015-04-28 13:30:13 -070030)
31
Yu Liue4312402023-01-18 09:15:31 -080032func init() {
33 registerTestMutators(android.InitRegistrationContext)
34}
35
Jiyong Park6a43f042017-10-12 23:05:00 +090036func TestMain(m *testing.M) {
Paul Duffinc3e6ce02021-03-22 23:21:32 +000037 os.Exit(m.Run())
Jiyong Park6a43f042017-10-12 23:05:00 +090038}
39
Paul Duffin2e6f90e2021-03-22 23:20:25 +000040var prepareForCcTest = android.GroupFixturePreparers(
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090041 PrepareForIntegrationTestWithCc,
42 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
43 variables.VendorApiLevel = StringPtr("202404")
44 }),
45)
46
Yu Liue4312402023-01-18 09:15:31 -080047var apexVariationName = "apex28"
48var apexVersion = "28"
49
50func registerTestMutators(ctx android.RegistrationContext) {
51 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
52 ctx.BottomUp("apex", testApexMutator).Parallel()
Yu Liue4312402023-01-18 09:15:31 -080053 })
54}
55
Yu Liue4312402023-01-18 09:15:31 -080056func testApexMutator(mctx android.BottomUpMutatorContext) {
57 modules := mctx.CreateVariations(apexVariationName)
58 apexInfo := android.ApexInfo{
59 ApexVariationName: apexVariationName,
60 MinSdkVersion: android.ApiLevelForTest(apexVersion),
61 }
62 mctx.SetVariationProvider(modules[0], android.ApexInfoProvider, apexInfo)
63}
64
Paul Duffin8567f222021-03-23 00:02:06 +000065// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000066//
67// See testCc for an explanation as to how to stop using this deprecated method.
68//
69// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080070func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070071 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000072 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000073 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090074}
75
Paul Duffin8567f222021-03-23 00:02:06 +000076// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000077//
Paul Duffin8567f222021-03-23 00:02:06 +000078// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
Paul Duffin02a3d652021-02-24 18:51:54 +000079// easier to customize the test behavior.
80//
81// If it is necessary to customize the behavior of an existing test that uses this then please first
Paul Duffin8567f222021-03-23 00:02:06 +000082// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000083// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
84// that it did not change the test behavior unexpectedly.
85//
86// deprecated
Logan Chienf3511742017-10-31 18:04:35 +080087func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080088 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000089 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +000090 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +080091}
92
Paul Duffin8567f222021-03-23 00:02:06 +000093// testCcErrorWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000094//
95// See testCc for an explanation as to how to stop using this deprecated method.
96//
97// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +090098func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +080099 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800100
Paul Duffin8567f222021-03-23 00:02:06 +0000101 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000102 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
103 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800104}
105
Paul Duffin8567f222021-03-23 00:02:06 +0000106// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000107//
108// See testCc for an explanation as to how to stop using this deprecated method.
109//
110// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900111func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900112 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000113 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900114 testCcErrorWithConfig(t, pattern, config)
115 return
116}
117
Logan Chienf3511742017-10-31 18:04:35 +0800118const (
Colin Cross7113d202019-11-20 16:39:12 -0800119 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900120 vendorVariant = "android_vendor_arm64_armv8-a_shared"
121 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800122 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800123)
124
Paul Duffindb462dd2021-03-21 22:01:55 +0000125// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
126// running it in a fixture that requires all source files to exist.
127func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
128 android.GroupFixturePreparers(
129 PrepareForTestWithCcDefaultModules,
130 android.PrepareForTestDisallowNonExistentPaths,
131 ).RunTest(t)
132}
133
Jiyong Park6a43f042017-10-12 23:05:00 +0900134func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400135 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900136 ctx := testCc(t, `
137 cc_library {
138 name: "libTest",
139 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700140 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800141 nocrt: true,
142 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900143 vendor_available: true,
144 target: {
145 vendor: {
146 srcs: ["bar.c"],
147 },
148 },
149 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900150 `)
151
Logan Chienf3511742017-10-31 18:04:35 +0800152 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900153 var objs []string
154 for _, o := range ld.Inputs {
155 objs = append(objs, o.Base())
156 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800157 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900158 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
159 }
160}
161
Justin Yun7f99ec72021-04-12 13:19:28 +0900162func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
163 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
164 partitionDefined := false
165 checkPartition := func(specific bool, partition string) {
166 if specific {
167 if expected != partition && !partitionDefined {
168 // The variant is installed to the 'partition'
169 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
170 }
171 partitionDefined = true
172 } else {
173 // The variant is not installed to the 'partition'
174 if expected == partition {
175 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
176 }
177 }
178 }
179 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800180 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900181 }
182 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800183 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900184 }
185 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800186 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900187 }
188 systemExtSpecific := func(m *Module) bool {
189 return m.SystemExtSpecific()
190 }
191 checkPartition(socSpecific(mod), "vendor")
192 checkPartition(deviceSpecific(mod), "odm")
193 checkPartition(productSpecific(mod), "product")
194 checkPartition(systemExtSpecific(mod), "system_ext")
195 if !partitionDefined && expected != "system" {
196 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
197 " but installed to system partition", variant, name, expected)
198 }
199}
200
201func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400202 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900203 t.Helper()
204 ctx := prepareForCcTest.RunTestWithBp(t, `
205 cc_library {
206 name: "libsystem",
207 }
208 cc_library {
209 name: "libsystem_ext",
210 system_ext_specific: true,
211 }
212 cc_library {
213 name: "libproduct",
214 product_specific: true,
215 }
216 cc_library {
217 name: "libvendor",
218 vendor: true,
219 }
220 cc_library {
221 name: "libodm",
222 device_specific: true,
223 }
224 cc_library {
225 name: "liball_available",
226 vendor_available: true,
227 product_available: true,
228 }
229 cc_library {
230 name: "libsystem_ext_all_available",
231 system_ext_specific: true,
232 vendor_available: true,
233 product_available: true,
234 }
235 cc_library {
236 name: "liball_available_odm",
237 odm_available: true,
238 product_available: true,
239 }
240 cc_library {
241 name: "libproduct_vendoravailable",
242 product_specific: true,
243 vendor_available: true,
244 }
245 cc_library {
246 name: "libproduct_odmavailable",
247 product_specific: true,
248 odm_available: true,
249 }
250 `).TestContext
251
252 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
253 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
254 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
255 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
256 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
257
258 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
259 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
260 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
261
262 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
263 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
264 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
265
266 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
267 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
268 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
269
270 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
271 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
272
273 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
274 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
275}
276
Colin Crossf61d03d2023-11-02 16:56:39 -0700277func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900278 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700279 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800280 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900281 assertArrayString(t, actual, expected)
282}
283
Chris Parsons79d66a52020-06-05 17:26:16 -0400284func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400285 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400286 bp := `
287 cc_test_library {
288 name: "test_lib",
289 srcs: ["test_lib.cpp"],
290 gtest: false,
291 }
292
293 cc_test {
294 name: "main_test",
295 data_libs: ["test_lib"],
296 gtest: false,
297 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400298 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400299
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000300 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400301
302 ctx := testCcWithConfig(t, config)
303 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
304 testBinary := module.(*Module).linker.(*testBinary)
305 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
306 if err != nil {
307 t.Errorf("Expected cc_test to produce output files, error: %s", err)
308 return
309 }
310 if len(outputFiles) != 1 {
311 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
312 return
313 }
314 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800315 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400316 return
317 }
318
319 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400320 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400321
322 if !strings.HasSuffix(outputPath, "/main_test") {
323 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
324 return
325 }
326 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
327 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
328 return
329 }
330}
331
Chris Parsons216e10a2020-07-09 17:12:52 -0400332func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400333 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400334 bp := `
335 cc_test_library {
336 name: "test_lib",
337 srcs: ["test_lib.cpp"],
338 relative_install_path: "foo/bar/baz",
339 gtest: false,
340 }
341
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400342 cc_binary {
343 name: "test_bin",
344 relative_install_path: "foo/bar/baz",
345 compile_multilib: "both",
346 }
347
Chris Parsons216e10a2020-07-09 17:12:52 -0400348 cc_test {
349 name: "main_test",
350 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400351 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400352 gtest: false,
353 }
354 `
355
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000356 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400357
358 ctx := testCcWithConfig(t, config)
359 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
360 testBinary := module.(*Module).linker.(*testBinary)
361 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
362 if err != nil {
363 t.Fatalf("Expected cc_test to produce output files, error: %s", err)
364 }
365 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400366 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400367 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400368 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800369 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400370 }
371
372 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400373
374 if !strings.HasSuffix(outputPath, "/main_test") {
375 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
376 }
Colin Crossaa255532020-07-03 13:18:24 -0700377 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons216e10a2020-07-09 17:12:52 -0400378 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
379 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400380 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400381 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400382 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
383 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
384 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
385 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400386}
387
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000388func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400389 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000390 bp := `
391 cc_test {
392 name: "main_test",
393 srcs: ["main_test.cpp"],
394 test_suites: [
395 "suite_1",
396 "suite_2",
397 ],
398 gtest: false,
399 }
400 `
401
402 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
403 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
404
405 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
406 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
407 if len(compatEntries) != 2 {
408 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
409 }
410 if compatEntries[0] != "suite_1" {
411 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
412 " but was '%s'", compatEntries[0])
413 }
414 if compatEntries[1] != "suite_2" {
415 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
416 " but was '%s'", compatEntries[1])
417 }
418}
419
420func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400421 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000422 bp := `
423 cc_test_library {
424 name: "main_test_lib",
425 srcs: ["main_test_lib.cpp"],
426 test_suites: [
427 "suite_1",
428 "suite_2",
429 ],
430 gtest: false,
431 }
432 `
433
434 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
435 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
436
437 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
438 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
439 if len(compatEntries) != 2 {
440 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
441 }
442 if compatEntries[0] != "suite_1" {
443 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
444 " but was '%s'", compatEntries[0])
445 }
446 if compatEntries[1] != "suite_2" {
447 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
448 " but was '%s'", compatEntries[1])
449 }
450}
451
Jooyung Hana70f0672019-01-18 15:20:43 +0900452func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400453 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900454 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900455 testCc(t, `
456 cc_library {
457 name: "libllndk",
458 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700459 llndk: {
460 symbol_file: "libllndk.map.txt",
461 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900462 }
463
464 cc_library {
465 name: "libdoubleloadable",
466 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900467 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900468 double_loadable: true,
469 }
470 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900471 // okay to link : double_loadable -> double_loadable
472 testCc(t, `
473 cc_library {
474 name: "libdoubleloadable1",
475 shared_libs: ["libdoubleloadable2"],
476 vendor_available: true,
477 double_loadable: true,
478 }
479
480 cc_library {
481 name: "libdoubleloadable2",
482 vendor_available: true,
483 double_loadable: true,
484 }
485 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900486 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900487 testCc(t, `
488 cc_library {
489 name: "libdoubleloadable",
490 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900491 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900492 double_loadable: true,
493 shared_libs: ["libnondoubleloadable"],
494 }
495
496 cc_library {
497 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900498 vendor_available: true,
499 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900500 double_loadable: true,
501 }
502 `)
503 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
504 testCc(t, `
505 cc_library {
506 name: "libllndk",
507 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700508 llndk: {
509 symbol_file: "libllndk.map.txt",
510 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900511 }
512
513 cc_library {
514 name: "libcoreonly",
515 shared_libs: ["libvendoravailable"],
516 }
517
518 // indirect dependency of LLNDK
519 cc_library {
520 name: "libvendoravailable",
521 vendor_available: true,
522 double_loadable: true,
523 }
524 `)
525}
526
527func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400528 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900529 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900530 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
531 cc_library {
532 name: "libllndk",
533 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700534 llndk: {
535 symbol_file: "libllndk.map.txt",
536 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900537 }
538
539 cc_library {
540 name: "libnondoubleloadable",
541 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900542 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900543 }
544 `)
545
546 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
547 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
548 cc_library {
549 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700550 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900551 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700552 llndk: {
553 symbol_file: "libllndk.map.txt",
554 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900555 }
556
557 cc_library {
558 name: "libnondoubleloadable",
559 vendor_available: true,
560 }
561 `)
562
Jooyung Hana70f0672019-01-18 15:20:43 +0900563 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
564 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
565 cc_library {
566 name: "libllndk",
567 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700568 llndk: {
569 symbol_file: "libllndk.map.txt",
570 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900571 }
572
573 cc_library {
574 name: "libcoreonly",
575 shared_libs: ["libvendoravailable"],
576 }
577
578 // indirect dependency of LLNDK
579 cc_library {
580 name: "libvendoravailable",
581 vendor_available: true,
582 }
583 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900584
585 // The error is not from 'client' but from 'libllndk'
586 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
587 cc_library {
588 name: "client",
589 vendor_available: true,
590 double_loadable: true,
591 shared_libs: ["libllndk"],
592 }
593 cc_library {
594 name: "libllndk",
595 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700596 llndk: {
597 symbol_file: "libllndk.map.txt",
598 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900599 }
600 cc_library {
601 name: "libnondoubleloadable",
602 vendor_available: true,
603 }
604 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800605}
606
Jooyung Han38002912019-05-16 04:01:54 +0900607func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400608 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800609 bp := `
610 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800611 name: "libvendor",
612 vendor: true,
613 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800614 vndk_prebuilt_shared {
615 name: "prevndk",
616 version: "27",
617 target_arch: "arm",
618 binder32bit: true,
619 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900620 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800621 vndk: {
622 enabled: true,
623 },
624 arch: {
625 arm: {
626 srcs: ["liba.so"],
627 },
628 },
629 }
630 cc_library {
631 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700632 llndk: {
633 symbol_file: "libllndk.map.txt",
634 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800635 }
636 cc_library {
637 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700638 llndk: {
639 symbol_file: "libllndkprivate.map.txt",
640 private: true,
641 }
Colin Cross78212242021-01-06 14:51:30 -0800642 }
Colin Cross78212242021-01-06 14:51:30 -0800643 llndk_libraries_txt {
644 name: "llndk.libraries.txt",
645 }
Colin Cross78212242021-01-06 14:51:30 -0800646 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800647
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000648 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900649 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800650 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900651
Colin Crossfb0c16e2019-11-20 17:12:35 -0800652 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900653
Jooyung Han38002912019-05-16 04:01:54 +0900654 tests := []struct {
655 variant string
656 name string
657 expected string
658 }{
Jooyung Han38002912019-05-16 04:01:54 +0900659 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800660 {vendorVariant, "libllndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +0900661 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +0900662 {coreVariant, "libllndk", "native:platform"},
663 }
664 for _, test := range tests {
665 t.Run(test.name, func(t *testing.T) {
666 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
667 assertString(t, module.makeLinkType, test.expected)
668 })
669 }
670}
671
Jeff Gaston294356f2017-09-27 17:05:30 -0700672var staticLinkDepOrderTestCases = []struct {
673 // This is a string representation of a map[moduleName][]moduleDependency .
674 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800675 inStatic string
676
677 // This is a string representation of a map[moduleName][]moduleDependency .
678 // It models the dependencies declared in an Android.bp file.
679 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700680
681 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
682 // The keys of allOrdered specify which modules we would like to check.
683 // The values of allOrdered specify the expected result (of the transitive closure of all
684 // dependencies) for each module to test
685 allOrdered string
686
687 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
688 // The keys of outOrdered specify which modules we would like to check.
689 // The values of outOrdered specify the expected result (of the ordered linker command line)
690 // for each module to test.
691 outOrdered string
692}{
693 // Simple tests
694 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800695 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700696 outOrdered: "",
697 },
698 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800699 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700700 outOrdered: "a:",
701 },
702 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800703 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700704 outOrdered: "a:b; b:",
705 },
706 // Tests of reordering
707 {
708 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800709 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700710 outOrdered: "a:b,c,d; b:d; c:d; d:",
711 },
712 {
713 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800714 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700715 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
716 },
717 {
718 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800719 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700720 outOrdered: "a:d,b,e,c; d:b; e:c",
721 },
722 {
723 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800724 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700725 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
726 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
727 },
728 {
729 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800730 inStatic: "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700731 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
732 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
733 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800734 // shared dependencies
735 {
736 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
737 // So, we don't actually have to check that a shared dependency of c will change the order
738 // of a library that depends statically on b and on c. We only need to check that if c has
739 // a shared dependency on b, that that shows up in allOrdered.
740 inShared: "c:b",
741 allOrdered: "c:b",
742 outOrdered: "c:",
743 },
744 {
745 // This test doesn't actually include any shared dependencies but it's a reminder of what
746 // the second phase of the above test would look like
747 inStatic: "a:b,c; c:b",
748 allOrdered: "a:c,b; c:b",
749 outOrdered: "a:c,b; c:b",
750 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700751 // tiebreakers for when two modules specifying different orderings and there is no dependency
752 // to dictate an order
753 {
754 // if the tie is between two modules at the end of a's deps, then a's order wins
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800755 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700756 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
757 },
758 {
759 // if the tie is between two modules at the start of a's deps, then c's order is used
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800760 inStatic: "a1:d,e,b1,c1; b1:d,e; c1:e,d; a2:d,e,b2,c2; b2:d,e; c2:d,e",
Jeff Gaston294356f2017-09-27 17:05:30 -0700761 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
762 },
763 // Tests involving duplicate dependencies
764 {
765 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800766 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700767 outOrdered: "a:c,b",
768 },
769 {
770 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800771 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700772 outOrdered: "a:d,c,b",
773 },
774 // Tests to confirm the nonexistence of infinite loops.
775 // These cases should never happen, so as long as the test terminates and the
776 // result is deterministic then that should be fine.
777 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800778 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700779 outOrdered: "a:a",
780 },
781 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800782 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700783 allOrdered: "a:b,c; b:c,a; c:a,b",
784 outOrdered: "a:b; b:c; c:a",
785 },
786 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800787 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700788 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
789 outOrdered: "a:c,b; b:a,c; c:b,a",
790 },
791}
792
793// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
794func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
795 // convert from "a:b,c; d:e" to "a:b,c;d:e"
796 strippedText := strings.Replace(text, " ", "", -1)
797 if len(strippedText) < 1 {
798 return []android.Path{}, make(map[android.Path][]android.Path, 0)
799 }
800 allDeps = make(map[android.Path][]android.Path, 0)
801
802 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
803 moduleTexts := strings.Split(strippedText, ";")
804
805 outputForModuleName := func(moduleName string) android.Path {
806 return android.PathForTesting(moduleName)
807 }
808
809 for _, moduleText := range moduleTexts {
810 // convert from "a:b,c" to ["a", "b,c"]
811 components := strings.Split(moduleText, ":")
812 if len(components) != 2 {
813 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
814 }
815 moduleName := components[0]
816 moduleOutput := outputForModuleName(moduleName)
817 modulesInOrder = append(modulesInOrder, moduleOutput)
818
819 depString := components[1]
820 // convert from "b,c" to ["b", "c"]
821 depNames := strings.Split(depString, ",")
822 if len(depString) < 1 {
823 depNames = []string{}
824 }
825 var deps []android.Path
826 for _, depName := range depNames {
827 deps = append(deps, outputForModuleName(depName))
828 }
829 allDeps[moduleOutput] = deps
830 }
831 return modulesInOrder, allDeps
832}
833
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800834func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400835 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700836 ctx := testCc(t, `
837 cc_library {
838 name: "a",
839 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900840 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700841 }
842 cc_library {
843 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900844 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700845 }
846 cc_library {
847 name: "c",
848 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900849 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700850 }
851 cc_library {
852 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900853 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700854 }
855
856 `)
857
Colin Cross7113d202019-11-20 16:39:12 -0800858 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700859 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800860 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
861 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400862 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700863
864 if !reflect.DeepEqual(actual, expected) {
865 t.Errorf("staticDeps orderings were not propagated correctly"+
866 "\nactual: %v"+
867 "\nexpected: %v",
868 actual,
869 expected,
870 )
871 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900872}
Jeff Gaston294356f2017-09-27 17:05:30 -0700873
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800874func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400875 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800876 ctx := testCc(t, `
877 cc_library {
878 name: "a",
879 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900880 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800881 }
882 cc_library {
883 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900884 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800885 }
886 cc_library {
887 name: "c",
888 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900889 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800890 }
891
892 `)
893
Colin Cross7113d202019-11-20 16:39:12 -0800894 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800895 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800896 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
897 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400898 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800899
900 if !reflect.DeepEqual(actual, expected) {
901 t.Errorf("staticDeps orderings did not account for shared libs"+
902 "\nactual: %v"+
903 "\nexpected: %v",
904 actual,
905 expected,
906 )
907 }
908}
909
Jooyung Hanb04a4992020-03-13 18:57:35 +0900910func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700911 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900912 if !reflect.DeepEqual(actual, expected) {
913 t.Errorf(message+
914 "\nactual: %v"+
915 "\nexpected: %v",
916 actual,
917 expected,
918 )
919 }
920}
921
Jooyung Han61b66e92020-03-21 14:21:46 +0000922func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400923 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800924 result := prepareForCcTest.RunTestWithBp(t, `
925 cc_library {
926 name: "libllndk",
927 stubs: { versions: ["1", "2"] },
928 llndk: {
929 symbol_file: "libllndk.map.txt",
930 },
931 export_include_dirs: ["include"],
932 }
933
934 cc_prebuilt_library_shared {
935 name: "libllndkprebuilt",
936 stubs: { versions: ["1", "2"] },
937 llndk: {
938 symbol_file: "libllndkprebuilt.map.txt",
939 },
940 }
941
942 cc_library {
943 name: "libllndk_with_external_headers",
944 stubs: { versions: ["1", "2"] },
945 llndk: {
946 symbol_file: "libllndk.map.txt",
947 export_llndk_headers: ["libexternal_llndk_headers"],
948 },
949 header_libs: ["libexternal_headers"],
950 export_header_lib_headers: ["libexternal_headers"],
951 }
952 cc_library_headers {
953 name: "libexternal_headers",
954 export_include_dirs: ["include"],
955 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900956 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800957 }
958 cc_library_headers {
959 name: "libexternal_llndk_headers",
960 export_include_dirs: ["include_llndk"],
961 llndk: {
962 symbol_file: "libllndk.map.txt",
963 },
964 vendor_available: true,
965 }
966
967 cc_library {
968 name: "libllndk_with_override_headers",
969 stubs: { versions: ["1", "2"] },
970 llndk: {
971 symbol_file: "libllndk.map.txt",
972 override_export_include_dirs: ["include_llndk"],
973 },
974 export_include_dirs: ["include"],
975 }
976 `)
977 actual := result.ModuleVariantsForTests("libllndk")
978 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900979 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800980 actual = append(actual[:i], actual[i+1:]...)
981 i--
982 }
983 }
984 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900985 "android_vendor_arm64_armv8-a_shared",
986 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800987 }
988 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
989
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900990 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Han33eb6152024-03-11 15:46:48 +0900991 android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800992
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800993 checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
994 t.Helper()
995 m := result.ModuleForTests(module, variant).Module()
Colin Cross5a377182023-12-14 14:46:23 -0800996 f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800997 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
998 expectedDirs, f.IncludeDirs)
999 }
1000
1001 checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001002 checkExportedIncludeDirs("libllndk", "android_vendor_arm64_armv8-a_shared", "include")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001003 checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001004 checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor_arm64_armv8-a_shared", "include_llndk")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001005 checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001006 checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor_arm64_armv8-a_shared", "include_llndk")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001007}
1008
Jiyong Parka46a4d52017-12-14 19:54:34 +09001009func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001010 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001011 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001012 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001013 name: "libllndk_headers",
1014 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001015 llndk: {
1016 llndk_headers: true,
1017 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001018 }
1019 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001020 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001021 llndk: {
1022 symbol_file: "libllndk.map.txt",
1023 export_llndk_headers: ["libllndk_headers"],
1024 }
Colin Cross0477b422020-10-13 18:43:54 -07001025 }
1026
1027 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001028 name: "libvendor",
1029 shared_libs: ["libllndk"],
1030 vendor: true,
1031 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001032 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001033 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001034 }
1035 `)
1036
1037 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001038 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001039 cflags := cc.Args["cFlags"]
1040 if !strings.Contains(cflags, "-Imy_include") {
1041 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1042 }
1043}
1044
Logan Chien43d34c32017-12-20 01:17:32 +08001045func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1046 actual := module.Properties.AndroidMkRuntimeLibs
1047 if !reflect.DeepEqual(actual, expected) {
1048 t.Errorf("incorrect runtime_libs for shared libs"+
1049 "\nactual: %v"+
1050 "\nexpected: %v",
1051 actual,
1052 expected,
1053 )
1054 }
1055}
1056
1057const runtimeLibAndroidBp = `
1058 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001059 name: "liball_available",
1060 vendor_available: true,
1061 product_available: true,
1062 no_libcrt : true,
1063 nocrt : true,
1064 system_shared_libs : [],
1065 }
1066 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001067 name: "libvendor_available1",
1068 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001069 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001070 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001071 nocrt : true,
1072 system_shared_libs : [],
1073 }
1074 cc_library {
1075 name: "libvendor_available2",
1076 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001077 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001078 target: {
1079 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001080 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001081 }
1082 },
Yi Konge7fe9912019-06-02 00:53:50 -07001083 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001084 nocrt : true,
1085 system_shared_libs : [],
1086 }
1087 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001088 name: "libproduct_vendor",
1089 product_specific: true,
1090 vendor_available: true,
1091 no_libcrt : true,
1092 nocrt : true,
1093 system_shared_libs : [],
1094 }
1095 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001096 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001097 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001098 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001099 nocrt : true,
1100 system_shared_libs : [],
1101 }
1102 cc_library {
1103 name: "libvendor1",
1104 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001105 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001106 nocrt : true,
1107 system_shared_libs : [],
1108 }
1109 cc_library {
1110 name: "libvendor2",
1111 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001112 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001113 no_libcrt : true,
1114 nocrt : true,
1115 system_shared_libs : [],
1116 }
1117 cc_library {
1118 name: "libproduct_available1",
1119 product_available: true,
1120 runtime_libs: ["liball_available"],
1121 no_libcrt : true,
1122 nocrt : true,
1123 system_shared_libs : [],
1124 }
1125 cc_library {
1126 name: "libproduct1",
1127 product_specific: true,
1128 no_libcrt : true,
1129 nocrt : true,
1130 system_shared_libs : [],
1131 }
1132 cc_library {
1133 name: "libproduct2",
1134 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001135 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
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`
1141
1142func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001143 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001144 ctx := testCc(t, runtimeLibAndroidBp)
1145
1146 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001147 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001148
Justin Yun8a2600c2020-12-07 12:44:03 +09001149 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1150 checkRuntimeLibs(t, []string{"liball_available"}, module)
1151
1152 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1153 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001154
1155 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001156 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001157
1158 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1159 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001160 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001161
Justin Yun8a2600c2020-12-07 12:44:03 +09001162 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1163 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001164
1165 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001166 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001167
1168 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1169 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001170 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001171
1172 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1173 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1174
1175 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001176 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001177}
1178
1179func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001180 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001181 ctx := testCc(t, runtimeLibAndroidBp)
1182
Colin Cross7113d202019-11-20 16:39:12 -08001183 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001184 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1185 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001186
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001187 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001188 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001189 checkRuntimeLibs(t, nil, module)
1190}
1191
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001192func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001193 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001194 actual := module.Properties.AndroidMkStaticLibs
1195 if !reflect.DeepEqual(actual, expected) {
1196 t.Errorf("incorrect static_libs"+
1197 "\nactual: %v"+
1198 "\nexpected: %v",
1199 actual,
1200 expected,
1201 )
1202 }
1203}
1204
1205const staticLibAndroidBp = `
1206 cc_library {
1207 name: "lib1",
1208 }
1209 cc_library {
1210 name: "lib2",
1211 static_libs: ["lib1"],
1212 }
1213`
1214
1215func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001216 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001217 ctx := testCc(t, staticLibAndroidBp)
1218
1219 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001220 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001221 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001222 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001223
1224 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001225 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001226 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1227 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001228 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001229}
1230
Jiyong Parkd08b6972017-09-26 10:50:54 +09001231var compilerFlagsTestCases = []struct {
1232 in string
1233 out bool
1234}{
1235 {
1236 in: "a",
1237 out: false,
1238 },
1239 {
1240 in: "-a",
1241 out: true,
1242 },
1243 {
1244 in: "-Ipath/to/something",
1245 out: false,
1246 },
1247 {
1248 in: "-isystempath/to/something",
1249 out: false,
1250 },
1251 {
1252 in: "--coverage",
1253 out: false,
1254 },
1255 {
1256 in: "-include a/b",
1257 out: true,
1258 },
1259 {
1260 in: "-include a/b c/d",
1261 out: false,
1262 },
1263 {
1264 in: "-DMACRO",
1265 out: true,
1266 },
1267 {
1268 in: "-DMAC RO",
1269 out: false,
1270 },
1271 {
1272 in: "-a -b",
1273 out: false,
1274 },
1275 {
1276 in: "-DMACRO=definition",
1277 out: true,
1278 },
1279 {
1280 in: "-DMACRO=defi nition",
1281 out: true, // TODO(jiyong): this should be false
1282 },
1283 {
1284 in: "-DMACRO(x)=x + 1",
1285 out: true,
1286 },
1287 {
1288 in: "-DMACRO=\"defi nition\"",
1289 out: true,
1290 },
1291}
1292
1293type mockContext struct {
1294 BaseModuleContext
1295 result bool
1296}
1297
1298func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1299 // CheckBadCompilerFlags calls this function when the flag should be rejected
1300 ctx.result = false
1301}
1302
1303func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001304 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001305 for _, testCase := range compilerFlagsTestCases {
1306 ctx := &mockContext{result: true}
1307 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1308 if ctx.result != testCase.out {
1309 t.Errorf("incorrect output:")
1310 t.Errorf(" input: %#v", testCase.in)
1311 t.Errorf(" expected: %#v", testCase.out)
1312 t.Errorf(" got: %#v", ctx.result)
1313 }
1314 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001315}
Jiyong Park374510b2018-03-19 18:23:01 +09001316
Jiyong Park37b25202018-07-11 10:49:27 +09001317func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001318 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001319 ctx := testCc(t, `
1320 cc_library_shared {
1321 name: "librecovery",
1322 recovery: true,
1323 }
1324 cc_library_shared {
1325 name: "librecovery32",
1326 recovery: true,
1327 compile_multilib:"32",
1328 }
Jiyong Park5baac542018-08-28 09:55:37 +09001329 cc_library_shared {
1330 name: "libHalInRecovery",
1331 recovery_available: true,
1332 vendor: true,
1333 }
Jiyong Park37b25202018-07-11 10:49:27 +09001334 `)
1335
1336 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001337 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001338 if len(variants) != 1 || !android.InList(arm64, variants) {
1339 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1340 }
1341
1342 variants = ctx.ModuleVariantsForTests("librecovery32")
1343 if android.InList(arm64, variants) {
1344 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1345 }
Jiyong Park5baac542018-08-28 09:55:37 +09001346
1347 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1348 if !recoveryModule.Platform() {
1349 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1350 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001351}
Jiyong Park5baac542018-08-28 09:55:37 +09001352
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001353func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001354 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001355 bp := `
1356 cc_prebuilt_test_library_shared {
1357 name: "test_lib",
1358 relative_install_path: "foo/bar/baz",
1359 srcs: ["srcpath/dontusethispath/baz.so"],
1360 }
1361
1362 cc_test {
1363 name: "main_test",
1364 data_libs: ["test_lib"],
1365 gtest: false,
1366 }
1367 `
1368
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001369 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001370
1371 ctx := testCcWithConfig(t, config)
1372 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
1373 testBinary := module.(*Module).linker.(*testBinary)
1374 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
1375 if err != nil {
1376 t.Fatalf("Expected cc_test to produce output files, error: %s", err)
1377 }
1378 if len(outputFiles) != 1 {
1379 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1380 }
1381 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001382 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001383 }
1384
1385 outputPath := outputFiles[0].String()
1386
1387 if !strings.HasSuffix(outputPath, "/main_test") {
1388 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1389 }
Colin Crossaa255532020-07-03 13:18:24 -07001390 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001391 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1392 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1393 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1394 }
1395}
1396
Jiyong Park7ed9de32018-10-15 22:25:07 +09001397func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001398 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001399 ctx := testCc(t, `
1400 cc_library_shared {
1401 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001402 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001403 stubs: {
1404 symbol_file: "foo.map.txt",
1405 versions: ["1", "2", "3"],
1406 },
1407 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001408
Jiyong Park7ed9de32018-10-15 22:25:07 +09001409 cc_library_shared {
1410 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001411 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001412 shared_libs: ["libFoo#1"],
1413 }`)
1414
1415 variants := ctx.ModuleVariantsForTests("libFoo")
1416 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001417 "android_arm64_armv8-a_shared",
1418 "android_arm64_armv8-a_shared_1",
1419 "android_arm64_armv8-a_shared_2",
1420 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001421 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001422 "android_arm_armv7-a-neon_shared",
1423 "android_arm_armv7-a-neon_shared_1",
1424 "android_arm_armv7-a-neon_shared_2",
1425 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001426 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001427 }
1428 variantsMismatch := false
1429 if len(variants) != len(expectedVariants) {
1430 variantsMismatch = true
1431 } else {
1432 for _, v := range expectedVariants {
1433 if !inList(v, variants) {
1434 variantsMismatch = false
1435 }
1436 }
1437 }
1438 if variantsMismatch {
1439 t.Errorf("variants of libFoo expected:\n")
1440 for _, v := range expectedVariants {
1441 t.Errorf("%q\n", v)
1442 }
1443 t.Errorf(", but got:\n")
1444 for _, v := range variants {
1445 t.Errorf("%q\n", v)
1446 }
1447 }
1448
Colin Cross7113d202019-11-20 16:39:12 -08001449 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001450 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001451 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001452 if !strings.Contains(libFlags, libFoo1StubPath) {
1453 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1454 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001455
Colin Cross7113d202019-11-20 16:39:12 -08001456 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001457 cFlags := libBarCompileRule.Args["cFlags"]
1458 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1459 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1460 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1461 }
Jiyong Park37b25202018-07-11 10:49:27 +09001462}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001463
Liz Kammer48cdbeb2023-03-17 10:17:50 -04001464func TestStubsForLibraryInMultipleApexes(t *testing.T) {
1465 t.Parallel()
1466 ctx := testCc(t, `
1467 cc_library_shared {
1468 name: "libFoo",
1469 srcs: ["foo.c"],
1470 stubs: {
1471 symbol_file: "foo.map.txt",
1472 versions: ["current"],
1473 },
1474 apex_available: ["bar", "a1"],
1475 }
1476
1477 cc_library_shared {
1478 name: "libBar",
1479 srcs: ["bar.c"],
1480 shared_libs: ["libFoo"],
1481 apex_available: ["a1"],
1482 }
1483
1484 cc_library_shared {
1485 name: "libA1",
1486 srcs: ["a1.c"],
1487 shared_libs: ["libFoo"],
1488 apex_available: ["a1"],
1489 }
1490
1491 cc_library_shared {
1492 name: "libBarA1",
1493 srcs: ["bara1.c"],
1494 shared_libs: ["libFoo"],
1495 apex_available: ["bar", "a1"],
1496 }
1497
1498 cc_library_shared {
1499 name: "libAnyApex",
1500 srcs: ["anyApex.c"],
1501 shared_libs: ["libFoo"],
1502 apex_available: ["//apex_available:anyapex"],
1503 }
1504
1505 cc_library_shared {
1506 name: "libBaz",
1507 srcs: ["baz.c"],
1508 shared_libs: ["libFoo"],
1509 apex_available: ["baz"],
1510 }
1511
1512 cc_library_shared {
1513 name: "libQux",
1514 srcs: ["qux.c"],
1515 shared_libs: ["libFoo"],
1516 apex_available: ["qux", "bar"],
1517 }`)
1518
1519 variants := ctx.ModuleVariantsForTests("libFoo")
1520 expectedVariants := []string{
1521 "android_arm64_armv8-a_shared",
1522 "android_arm64_armv8-a_shared_current",
1523 "android_arm_armv7-a-neon_shared",
1524 "android_arm_armv7-a-neon_shared_current",
1525 }
1526 variantsMismatch := false
1527 if len(variants) != len(expectedVariants) {
1528 variantsMismatch = true
1529 } else {
1530 for _, v := range expectedVariants {
1531 if !inList(v, variants) {
1532 variantsMismatch = false
1533 }
1534 }
1535 }
1536 if variantsMismatch {
1537 t.Errorf("variants of libFoo expected:\n")
1538 for _, v := range expectedVariants {
1539 t.Errorf("%q\n", v)
1540 }
1541 t.Errorf(", but got:\n")
1542 for _, v := range variants {
1543 t.Errorf("%q\n", v)
1544 }
1545 }
1546
1547 linkAgainstFoo := []string{"libBarA1"}
1548 linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
1549
1550 libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
1551 for _, lib := range linkAgainstFoo {
1552 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1553 libFlags := libLinkRule.Args["libFlags"]
1554 if !strings.Contains(libFlags, libFooPath) {
1555 t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
1556 }
1557 }
1558
1559 libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
1560 for _, lib := range linkAgainstFooStubs {
1561 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1562 libFlags := libLinkRule.Args["libFlags"]
1563 if !strings.Contains(libFlags, libFooStubPath) {
1564 t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
1565 }
1566 }
1567}
1568
Jooyung Hanb04a4992020-03-13 18:57:35 +09001569func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001570 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001571 for _, tc := range []struct{ moduleName, expected string }{
1572 {"libc", "__LIBC_API__"},
1573 {"libfoo", "__LIBFOO_API__"},
1574 {"libfoo@1", "__LIBFOO_1_API__"},
1575 {"libfoo-v1", "__LIBFOO_V1_API__"},
1576 {"libfoo.v1", "__LIBFOO_V1_API__"},
1577 } {
1578 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1579 }
1580}
1581
Liz Kammer83cf81b2022-09-22 08:24:20 -04001582func pathsToBase(paths android.Paths) []string {
1583 var ret []string
1584 for _, p := range paths {
1585 ret = append(ret, p.Base())
1586 }
1587 return ret
1588}
1589
1590func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001591 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001592 ctx := testCc(t, `
1593 cc_library_static {
1594 name: "foo",
1595 srcs: ["foo.c"],
1596 }
1597
1598 cc_library_static {
1599 name: "bar",
1600 srcs: ["bar.c"],
1601 }
1602
1603 cc_library_shared {
1604 name: "qux",
1605 srcs: ["qux.c"],
1606 }
1607
1608 cc_library_static {
1609 name: "baz",
1610 srcs: ["baz.c"],
1611 static_libs: ["foo"],
1612 shared_libs: ["qux"],
1613 whole_static_libs: ["bar"],
1614 }`)
1615
1616 variant := "android_arm64_armv8-a_static"
1617 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1618
1619 // For static libraries, the object files of a whole static dep are included in the archive
1620 // directly
1621 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1622 t.Errorf("Expected input objects %q, got %q", w, g)
1623 }
1624
1625 // non whole static dependencies are not linked into the archive
1626 if len(arRule.Implicits) > 0 {
1627 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1628 }
1629}
1630
1631func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001632 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001633 ctx := testCc(t, `
1634 cc_library_static {
1635 name: "foo",
1636 srcs: ["foo.c"],
1637 }
1638
1639 cc_library_static {
1640 name: "bar",
1641 srcs: ["bar.c"],
1642 }
1643
1644 cc_library_shared {
1645 name: "qux",
1646 srcs: ["qux.c"],
1647 }
1648
1649 cc_library_shared {
1650 name: "baz",
1651 srcs: ["baz.c"],
1652 static_libs: ["foo"],
1653 shared_libs: ["qux"],
1654 whole_static_libs: ["bar"],
1655 }`)
1656
1657 variant := "android_arm64_armv8-a_shared"
1658 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1659 libFlags := linkRule.Args["libFlags"]
1660 // When dynamically linking, we expect static dependencies to be found on the command line
1661 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1662 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1663 }
1664 // When dynamically linking, we expect whole static dependencies to be found on the command line
1665 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1666 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1667 }
1668
1669 // When dynamically linking, we expect shared dependencies to be found on the command line
1670 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1671 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1672 }
1673
1674 // We should only have the objects from the shared library srcs, not the whole static dependencies
1675 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1676 t.Errorf("Expected input objects %q, got %q", w, g)
1677 }
1678}
1679
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001680func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001681 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001682 ctx := testCc(t, `
1683 cc_binary {
1684 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001685 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001686 static_executable: true,
1687 }`)
1688
Colin Cross7113d202019-11-20 16:39:12 -08001689 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001690 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1691 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001692 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001693 for _, lib := range systemStaticLibs {
1694 if !strings.Contains(libFlags, lib) {
1695 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1696 }
1697 }
1698 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1699 for _, lib := range systemSharedLibs {
1700 if strings.Contains(libFlags, lib) {
1701 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1702 }
1703 }
1704}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001705
1706func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001707 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001708 ctx := testCc(t, `
1709 cc_binary {
1710 name: "mybin",
1711 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001712 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001713 static_executable: true,
1714 stl: "none",
1715 }
1716
1717 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001718 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001719 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001720 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001721 stl: "none",
1722 }
1723
1724 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001725 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001726 srcs: ["foo.c"],
1727 stl: "none",
1728 stubs: {
1729 versions: ["1"],
1730 },
1731 }`)
1732
Colin Cross0de8a1e2020-09-18 14:15:30 -07001733 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1734 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001735 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001736
1737 if !reflect.DeepEqual(actual, expected) {
1738 t.Errorf("staticDeps orderings were not propagated correctly"+
1739 "\nactual: %v"+
1740 "\nexpected: %v",
1741 actual,
1742 expected,
1743 )
1744 }
1745}
Jooyung Han38002912019-05-16 04:01:54 +09001746
Jooyung Hand48f3c32019-08-23 11:18:57 +09001747func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001748 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001749 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1750 cc_library {
1751 name: "libA",
1752 srcs: ["foo.c"],
1753 shared_libs: ["libB"],
1754 stl: "none",
1755 }
1756
1757 cc_library {
1758 name: "libB",
1759 srcs: ["foo.c"],
1760 enabled: false,
1761 stl: "none",
1762 }
1763 `)
1764}
1765
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001766func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1767 bp := `
1768 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001769 name: "test_afl_fuzz_target",
1770 srcs: ["foo.c"],
1771 host_supported: true,
1772 static_libs: [
1773 "afl_fuzz_static_lib",
1774 ],
1775 shared_libs: [
1776 "afl_fuzz_shared_lib",
1777 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001778 fuzzing_frameworks: {
1779 afl: true,
1780 libfuzzer: false,
1781 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001782 }
1783 cc_library {
1784 name: "afl_fuzz_static_lib",
1785 host_supported: true,
1786 srcs: ["static_file.c"],
1787 }
1788 cc_library {
1789 name: "libfuzzer_only_static_lib",
1790 host_supported: true,
1791 srcs: ["static_file.c"],
1792 }
1793 cc_library {
1794 name: "afl_fuzz_shared_lib",
1795 host_supported: true,
1796 srcs: ["shared_file.c"],
1797 static_libs: [
1798 "second_static_lib",
1799 ],
1800 }
1801 cc_library_headers {
1802 name: "libafl_headers",
1803 vendor_available: true,
1804 host_supported: true,
1805 export_include_dirs: [
1806 "include",
1807 "instrumentation",
1808 ],
1809 }
1810 cc_object {
1811 name: "afl-compiler-rt",
1812 vendor_available: true,
1813 host_supported: true,
1814 cflags: [
1815 "-fPIC",
1816 ],
1817 srcs: [
1818 "instrumentation/afl-compiler-rt.o.c",
1819 ],
1820 }
1821 cc_library {
1822 name: "second_static_lib",
1823 host_supported: true,
1824 srcs: ["second_file.c"],
1825 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001826 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001827 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001828 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001829 srcs: [
1830 "aflpp_driver.c",
1831 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001832 }`
1833
1834 testEnv := map[string]string{
1835 "FUZZ_FRAMEWORK": "AFL",
1836 }
1837
1838 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001839
1840 checkPcGuardFlag := func(
1841 modName string, variantName string, shouldHave bool) {
1842 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1843
1844 cFlags, ok := cc.Args["cFlags"]
1845 if !ok {
1846 t.Errorf("Could not find cFlags for module %s and variant %s",
1847 modName, variantName)
1848 }
1849
1850 if strings.Contains(
1851 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1852 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1853 "Test failed for module %s and variant %s",
1854 !shouldHave, shouldHave, modName, variantName)
1855 }
1856 }
1857
Cory Barkera1da26f2022-06-07 20:12:06 +00001858 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001859 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001860
1861 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001862 checkPcGuardFlag(moduleName, variant+"_static", false)
1863 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001864
1865 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001866 checkPcGuardFlag(moduleName, variant+"_static", false)
1867 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001868
1869 ctx.ModuleForTests("afl_fuzz_shared_lib",
1870 "android_arm64_armv8-a_shared").Rule("cc")
1871 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001872 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1873}
1874
1875func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001876 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001877 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1878}
1879
1880func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001881 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001882 if runtime.GOOS != "linux" {
1883 t.Skip("requires linux")
1884 }
1885
1886 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001887}
1888
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001889// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1890// correctly.
1891func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001892 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001893 ctx := testCc(t, `
1894 cc_fuzz {
1895 name: "fuzz_smoke_test",
1896 srcs: ["foo.c"],
1897 }`)
1898
Paul Duffin075c4172019-12-19 19:06:13 +00001899 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001900 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1901}
1902
Jooyung Han38002912019-05-16 04:01:54 +09001903func assertString(t *testing.T, got, expected string) {
1904 t.Helper()
1905 if got != expected {
1906 t.Errorf("expected %q got %q", expected, got)
1907 }
1908}
1909
1910func assertArrayString(t *testing.T, got, expected []string) {
1911 t.Helper()
1912 if len(got) != len(expected) {
1913 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1914 return
1915 }
1916 for i := range got {
1917 if got[i] != expected[i] {
1918 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1919 i, expected[i], expected, got[i], got)
1920 return
1921 }
1922 }
1923}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001924
Jooyung Han0302a842019-10-30 18:43:49 +09001925func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1926 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001927 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001928}
1929
Colin Crosse1bb5d02019-09-24 14:55:04 -07001930func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001931 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001932 ctx := testCc(t, `
1933 cc_defaults {
1934 name: "defaults",
1935 srcs: ["foo.c"],
1936 static: {
1937 srcs: ["bar.c"],
1938 },
1939 shared: {
1940 srcs: ["baz.c"],
1941 },
1942 }
1943
1944 cc_library_static {
1945 name: "libstatic",
1946 defaults: ["defaults"],
1947 }
1948
1949 cc_library_shared {
1950 name: "libshared",
1951 defaults: ["defaults"],
1952 }
1953
1954 cc_library {
1955 name: "libboth",
1956 defaults: ["defaults"],
1957 }
1958
1959 cc_binary {
1960 name: "binary",
1961 defaults: ["defaults"],
1962 }`)
1963
Colin Cross7113d202019-11-20 16:39:12 -08001964 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001965 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1966 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
1967 }
Colin Cross7113d202019-11-20 16:39:12 -08001968 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001969 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1970 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
1971 }
Colin Cross7113d202019-11-20 16:39:12 -08001972 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001973 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
1974 t.Errorf("binary ld rule wanted %q, got %q", w, g)
1975 }
1976
Colin Cross7113d202019-11-20 16:39:12 -08001977 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001978 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1979 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
1980 }
Colin Cross7113d202019-11-20 16:39:12 -08001981 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001982 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1983 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
1984 }
1985}
Colin Crosseabaedd2020-02-06 17:01:55 -08001986
1987func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001988 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08001989 bp := `
1990 cc_defaults {
1991 name: "libfoo_defaults",
1992 srcs: ["foo.c"],
1993 cppflags: ["-DFOO"],
1994 product_variables: {
1995 debuggable: {
1996 cppflags: ["-DBAR"],
1997 },
1998 },
1999 }
2000
2001 cc_library {
2002 name: "libfoo",
2003 defaults: ["libfoo_defaults"],
2004 }
2005 `
2006
Paul Duffin8567f222021-03-23 00:02:06 +00002007 result := android.GroupFixturePreparers(
2008 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002009 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08002010
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002011 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2012 variables.Debuggable = BoolPtr(true)
2013 }),
2014 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08002015
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002016 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00002017 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08002018}
Colin Crosse4f6eba2020-09-22 18:11:25 -07002019
2020func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
2021 t.Parallel()
2022 bp := `
2023 cc_library_static {
2024 name: "libfoo",
2025 srcs: ["foo.c"],
2026 whole_static_libs: ["libbar"],
2027 }
2028
2029 cc_library_static {
2030 name: "libbar",
2031 whole_static_libs: ["libmissing"],
2032 }
2033 `
2034
Paul Duffin8567f222021-03-23 00:02:06 +00002035 result := android.GroupFixturePreparers(
2036 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002037 android.PrepareForTestWithAllowMissingDependencies,
2038 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002039
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002040 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002041 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002042
Paul Duffine84b1332021-03-12 11:59:43 +00002043 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07002044
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002045 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002046 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07002047}
Colin Crosse9fe2942020-11-10 18:12:15 -08002048
2049func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002050 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08002051 bp := `
2052 cc_binary {
2053 name: "bin",
2054 host_supported: true,
2055 shared_libs: ["libshared"],
2056 runtime_libs: ["libruntime"],
2057 srcs: [":gen"],
2058 }
2059
2060 cc_library_shared {
2061 name: "libshared",
2062 host_supported: true,
2063 shared_libs: ["libtransitive"],
2064 }
2065
2066 cc_library_shared {
2067 name: "libtransitive",
2068 host_supported: true,
2069 }
2070
2071 cc_library_shared {
2072 name: "libruntime",
2073 host_supported: true,
2074 }
2075
2076 cc_binary_host {
2077 name: "tool",
2078 srcs: ["foo.cpp"],
2079 }
2080
2081 genrule {
2082 name: "gen",
2083 tools: ["tool"],
2084 out: ["gen.cpp"],
2085 cmd: "$(location tool) $(out)",
2086 }
2087 `
2088
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002089 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002090 ctx := testCcWithConfig(t, config)
2091
2092 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2093 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2094 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2095 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2096 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2097
2098 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2099 t.Errorf("expected host bin dependency %q, got %q", w, g)
2100 }
2101
2102 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2103 t.Errorf("expected host bin dependency %q, got %q", w, g)
2104 }
2105
2106 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2107 t.Errorf("expected host bin dependency %q, got %q", w, g)
2108 }
2109
2110 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2111 t.Errorf("expected host bin dependency %q, got %q", w, g)
2112 }
2113
2114 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2115 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2116 }
2117
2118 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2119 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2120 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2121 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2122
2123 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2124 t.Errorf("expected device bin dependency %q, got %q", w, g)
2125 }
2126
2127 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2128 t.Errorf("expected device bin dependency %q, got %q", w, g)
2129 }
2130
2131 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2132 t.Errorf("expected device bin dependency %q, got %q", w, g)
2133 }
2134
2135 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2136 t.Errorf("expected device bin dependency %q, got %q", w, g)
2137 }
2138
2139 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2140 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2141 }
2142
2143}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002144
2145func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002146 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002147 ctx := testCc(t, `
2148 cc_library_shared {
2149 name: "libclient",
2150 srcs: ["foo.c"],
2151 shared_libs: ["libfoo#1"],
2152 }
2153
2154 cc_library_shared {
2155 name: "libfoo",
2156 srcs: ["foo.c"],
2157 shared_libs: ["libbar"],
2158 export_shared_lib_headers: ["libbar"],
2159 stubs: {
2160 symbol_file: "foo.map.txt",
2161 versions: ["1", "2", "3"],
2162 },
2163 }
2164
2165 cc_library_shared {
2166 name: "libbar",
2167 export_include_dirs: ["include/libbar"],
2168 srcs: ["foo.c"],
2169 }`)
2170
2171 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2172
2173 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2174 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2175 }
2176}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002177
Vinh Tran09581952023-05-16 16:03:20 -04002178func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002179 t.Parallel()
2180 ctx := android.GroupFixturePreparers(
2181 prepareForCcTest,
2182 aidl_library.PrepareForTestWithAidlLibrary,
2183 android.MockFS{
2184 "package_bar/Android.bp": []byte(`
2185 aidl_library {
2186 name: "bar",
2187 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002188 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002189 strip_import_prefix: "x",
2190 }
2191 `)}.AddToFixture(),
2192 android.MockFS{
2193 "package_foo/Android.bp": []byte(`
2194 aidl_library {
2195 name: "foo",
2196 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002197 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002198 strip_import_prefix: "a",
2199 deps: ["bar"],
2200 }
2201 cc_library {
2202 name: "libfoo",
2203 aidl: {
2204 libs: ["foo"],
2205 }
2206 }
2207 `),
2208 }.AddToFixture(),
2209 ).RunTest(t).TestContext
2210
2211 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002212
2213 android.AssertPathsRelativeToTopEquals(
2214 t,
2215 "aidl headers",
2216 []string{
2217 "package_bar/x/HeaderBar.aidl",
2218 "package_foo/a/HeaderFoo.aidl",
2219 "package_foo/a/b/Foo.aidl",
2220 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2221 },
2222 libfoo.Rule("aidl_library").Implicits,
2223 )
2224
Colin Crossf61d03d2023-11-02 16:56:39 -07002225 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002226 aidlCommand := manifest.Commands[0].GetCommand()
2227
2228 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2229 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2230 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2231 }
2232
2233 outputs := strings.Join(libfoo.AllOutputs(), " ")
2234
Vinh Tran09581952023-05-16 16:03:20 -04002235 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2236 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2237 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002238 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2239 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002240 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2241 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2242 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002243 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2244}
2245
Jooyung Hane197d8b2021-01-05 10:33:16 +09002246func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002247 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002248 ctx := android.GroupFixturePreparers(
2249 prepareForCcTest,
2250 aidl_library.PrepareForTestWithAidlLibrary,
2251 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002252 cc_library {
2253 name: "libfoo",
2254 srcs: ["a/Foo.aidl"],
2255 aidl: { flags: ["-Werror"], },
2256 }
2257 `)
2258
2259 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002260 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002261 aidlCommand := manifest.Commands[0].GetCommand()
2262 expectedAidlFlag := "-Werror"
2263 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2264 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2265 }
2266}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002267
Jooyung Han07f70c02021-11-06 07:08:45 +09002268func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002269 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002270 for _, tc := range []struct {
2271 name string
2272 sdkVersion string
2273 variant string
2274 expected string
2275 }{
2276 {
2277 name: "default is current",
2278 sdkVersion: "",
2279 variant: "android_arm64_armv8-a_static",
2280 expected: "platform_apis",
2281 },
2282 {
2283 name: "use sdk_version",
2284 sdkVersion: `sdk_version: "29"`,
2285 variant: "android_arm64_armv8-a_static",
2286 expected: "platform_apis",
2287 },
2288 {
2289 name: "use sdk_version(sdk variant)",
2290 sdkVersion: `sdk_version: "29"`,
2291 variant: "android_arm64_armv8-a_sdk_static",
2292 expected: "29",
2293 },
2294 {
2295 name: "use min_sdk_version",
2296 sdkVersion: `min_sdk_version: "29"`,
2297 variant: "android_arm64_armv8-a_static",
2298 expected: "29",
2299 },
2300 } {
2301 t.Run(tc.name, func(t *testing.T) {
2302 ctx := testCc(t, `
2303 cc_library {
2304 name: "libfoo",
2305 stl: "none",
2306 srcs: ["a/Foo.aidl"],
2307 `+tc.sdkVersion+`
2308 }
2309 `)
2310 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002311 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002312 aidlCommand := manifest.Commands[0].GetCommand()
2313 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2314 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2315 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2316 }
2317 })
2318 }
2319}
2320
Vinh Tran09581952023-05-16 16:03:20 -04002321func TestInvalidAidlProp(t *testing.T) {
2322 t.Parallel()
2323
2324 testCases := []struct {
2325 description string
2326 bp string
2327 }{
2328 {
2329 description: "Invalid use of aidl.libs and aidl.include_dirs",
2330 bp: `
2331 cc_library {
2332 name: "foo",
2333 aidl: {
2334 libs: ["foo_aidl"],
2335 include_dirs: ["bar/include"],
2336 }
2337 }
2338 `,
2339 },
2340 {
2341 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2342 bp: `
2343 cc_library {
2344 name: "foo",
2345 aidl: {
2346 libs: ["foo_aidl"],
2347 local_include_dirs: ["include"],
2348 }
2349 }
2350 `,
2351 },
2352 }
2353
2354 for _, testCase := range testCases {
2355 t.Run(testCase.description, func(t *testing.T) {
2356 bp := `
2357 aidl_library {
2358 name: "foo_aidl",
2359 srcs: ["Foo.aidl"],
2360 } ` + testCase.bp
2361 android.GroupFixturePreparers(
2362 prepareForCcTest,
2363 aidl_library.PrepareForTestWithAidlLibrary.
2364 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2365 ).RunTestWithBp(t, bp)
2366 })
2367 }
2368}
2369
Jiyong Parka008fb02021-03-16 17:15:53 +09002370func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002371 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002372 ctx := testCc(t, `
2373 cc_library_shared {
2374 name: "libfoo",
2375 srcs: ["foo.c"],
2376 min_sdk_version: "29",
2377 }`)
2378
2379 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2380 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2381}
2382
Vinh Tranf1924742022-06-24 16:40:11 -04002383func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002384 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002385 bp := `
2386 cc_library_shared {
2387 name: "libfoo",
2388 srcs: ["foo.c"],
2389 min_sdk_version: "S",
2390 }
2391 `
2392 result := android.GroupFixturePreparers(
2393 prepareForCcTest,
2394 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2395 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2396 }),
2397 ).RunTestWithBp(t, bp)
2398 ctx := result.TestContext
2399 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2400 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2401}
2402
Paul Duffin3cb603e2021-02-19 13:57:10 +00002403func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002404 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002405
2406 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2407 // embedded newline characters alone.
2408 trimIndentingSpaces := func(s string) string {
2409 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2410 }
2411
2412 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2413 t.Helper()
2414 expected = trimIndentingSpaces(expected)
2415 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2416 if expected != actual {
2417 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2418 }
2419 }
2420
2421 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2422
2423 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2424 t.Helper()
Colin Cross5a377182023-12-14 14:46:23 -08002425 exported, _ := android.SingletonModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002426 name := module.Name()
2427
2428 for _, checker := range checkers {
2429 checker(t, name, exported)
2430 }
2431 }
2432
2433 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2434 return func(t *testing.T, name string, exported FlagExporterInfo) {
2435 t.Helper()
2436 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2437 }
2438 }
2439
2440 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2441 return func(t *testing.T, name string, exported FlagExporterInfo) {
2442 t.Helper()
2443 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2444 }
2445 }
2446
2447 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2448 return func(t *testing.T, name string, exported FlagExporterInfo) {
2449 t.Helper()
2450 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2451 }
2452 }
2453
2454 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2455 return func(t *testing.T, name string, exported FlagExporterInfo) {
2456 t.Helper()
2457 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2458 }
2459 }
2460
2461 genRuleModules := `
2462 genrule {
2463 name: "genrule_foo",
2464 cmd: "generate-foo",
2465 out: [
2466 "generated_headers/foo/generated_header.h",
2467 ],
2468 export_include_dirs: [
2469 "generated_headers",
2470 ],
2471 }
2472
2473 genrule {
2474 name: "genrule_bar",
2475 cmd: "generate-bar",
2476 out: [
2477 "generated_headers/bar/generated_header.h",
2478 ],
2479 export_include_dirs: [
2480 "generated_headers",
2481 ],
2482 }
2483 `
2484
2485 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2486 ctx := testCc(t, genRuleModules+`
2487 cc_library {
2488 name: "libfoo",
2489 srcs: ["foo.c"],
2490 export_include_dirs: ["foo/standard"],
2491 export_system_include_dirs: ["foo/system"],
2492 generated_headers: ["genrule_foo"],
2493 export_generated_headers: ["genrule_foo"],
2494 }
2495
2496 cc_library {
2497 name: "libbar",
2498 srcs: ["bar.c"],
2499 shared_libs: ["libfoo"],
2500 export_include_dirs: ["bar/standard"],
2501 export_system_include_dirs: ["bar/system"],
2502 generated_headers: ["genrule_bar"],
2503 export_generated_headers: ["genrule_bar"],
2504 }
2505 `)
2506 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2507 checkIncludeDirs(t, ctx, foo,
2508 expectedIncludeDirs(`
2509 foo/standard
2510 .intermediates/genrule_foo/gen/generated_headers
2511 `),
2512 expectedSystemIncludeDirs(`foo/system`),
2513 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2514 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2515 )
2516
2517 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2518 checkIncludeDirs(t, ctx, bar,
2519 expectedIncludeDirs(`
2520 bar/standard
2521 .intermediates/genrule_bar/gen/generated_headers
2522 `),
2523 expectedSystemIncludeDirs(`bar/system`),
2524 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2525 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2526 )
2527 })
2528
2529 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2530 ctx := testCc(t, genRuleModules+`
2531 cc_library {
2532 name: "libfoo",
2533 srcs: ["foo.c"],
2534 export_include_dirs: ["foo/standard"],
2535 export_system_include_dirs: ["foo/system"],
2536 generated_headers: ["genrule_foo"],
2537 export_generated_headers: ["genrule_foo"],
2538 }
2539
2540 cc_library {
2541 name: "libbar",
2542 srcs: ["bar.c"],
2543 whole_static_libs: ["libfoo"],
2544 export_include_dirs: ["bar/standard"],
2545 export_system_include_dirs: ["bar/system"],
2546 generated_headers: ["genrule_bar"],
2547 export_generated_headers: ["genrule_bar"],
2548 }
2549 `)
2550 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2551 checkIncludeDirs(t, ctx, foo,
2552 expectedIncludeDirs(`
2553 foo/standard
2554 .intermediates/genrule_foo/gen/generated_headers
2555 `),
2556 expectedSystemIncludeDirs(`foo/system`),
2557 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2558 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2559 )
2560
2561 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2562 checkIncludeDirs(t, ctx, bar,
2563 expectedIncludeDirs(`
2564 bar/standard
2565 foo/standard
2566 .intermediates/genrule_foo/gen/generated_headers
2567 .intermediates/genrule_bar/gen/generated_headers
2568 `),
2569 expectedSystemIncludeDirs(`
2570 bar/system
2571 foo/system
2572 `),
2573 expectedGeneratedHeaders(`
2574 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2575 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2576 `),
2577 expectedOrderOnlyDeps(`
2578 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2579 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2580 `),
2581 )
2582 })
2583
Paul Duffin3cb603e2021-02-19 13:57:10 +00002584 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002585 ctx := android.GroupFixturePreparers(
2586 prepareForCcTest,
2587 aidl_library.PrepareForTestWithAidlLibrary,
2588 ).RunTestWithBp(t, `
2589 aidl_library {
2590 name: "libfoo_aidl",
2591 srcs: ["x/y/Bar.aidl"],
2592 strip_import_prefix: "x",
2593 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002594 cc_library_shared {
2595 name: "libfoo",
2596 srcs: [
2597 "foo.c",
2598 "b.aidl",
2599 "a.proto",
2600 ],
2601 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002602 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002603 export_aidl_headers: true,
2604 }
2605 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002606 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002607 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2608 checkIncludeDirs(t, ctx, foo,
2609 expectedIncludeDirs(`
2610 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002611 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002612 `),
2613 expectedSystemIncludeDirs(``),
2614 expectedGeneratedHeaders(`
2615 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2616 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2617 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002618 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2619 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2620 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002621 `),
2622 expectedOrderOnlyDeps(`
2623 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2624 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2625 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002626 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2627 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2628 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002629 `),
2630 )
2631 })
2632
Paul Duffin3cb603e2021-02-19 13:57:10 +00002633 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2634 ctx := testCc(t, genRuleModules+`
2635 cc_library_shared {
2636 name: "libfoo",
2637 srcs: [
2638 "foo.c",
2639 "b.aidl",
2640 "a.proto",
2641 ],
2642 proto: {
2643 export_proto_headers: true,
2644 }
2645 }
2646 `)
2647 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2648 checkIncludeDirs(t, ctx, foo,
2649 expectedIncludeDirs(`
2650 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2651 `),
2652 expectedSystemIncludeDirs(``),
2653 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002654 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2655 `),
2656 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002657 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2658 `),
2659 )
2660 })
2661
Paul Duffin33056e82021-02-19 13:49:08 +00002662 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002663 ctx := testCc(t, genRuleModules+`
2664 cc_library_shared {
2665 name: "libfoo",
2666 srcs: [
2667 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002668 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002669 "b.aidl",
2670 "a.proto",
2671 ],
2672 }
2673 `)
2674 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2675 checkIncludeDirs(t, ctx, foo,
2676 expectedIncludeDirs(`
2677 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2678 `),
2679 expectedSystemIncludeDirs(``),
2680 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002681 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002682 `),
2683 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002684 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2685 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002686 `),
2687 )
2688 })
2689}
Colin Crossae628182021-06-14 16:52:28 -07002690
2691func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002692 t.Parallel()
Liz Kammer08572c62021-09-30 10:11:04 -04002693 baseExpectedFlags := []string{
2694 "${config.ArmThumbCflags}",
2695 "${config.ArmCflags}",
2696 "${config.CommonGlobalCflags}",
2697 "${config.DeviceGlobalCflags}",
2698 "${config.ExternalCflags}",
2699 "${config.ArmToolchainCflags}",
2700 "${config.ArmArmv7ANeonCflags}",
2701 "${config.ArmGenericCflags}",
2702 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002703 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002704 }
2705
2706 expectedIncludes := []string{
2707 "external/foo/android_arm_export_include_dirs",
2708 "external/foo/lib32_export_include_dirs",
2709 "external/foo/arm_export_include_dirs",
2710 "external/foo/android_export_include_dirs",
2711 "external/foo/linux_export_include_dirs",
2712 "external/foo/export_include_dirs",
2713 "external/foo/android_arm_local_include_dirs",
2714 "external/foo/lib32_local_include_dirs",
2715 "external/foo/arm_local_include_dirs",
2716 "external/foo/android_local_include_dirs",
2717 "external/foo/linux_local_include_dirs",
2718 "external/foo/local_include_dirs",
2719 "external/foo",
2720 "external/foo/libheader1",
2721 "external/foo/libheader2",
2722 "external/foo/libwhole1",
2723 "external/foo/libwhole2",
2724 "external/foo/libstatic1",
2725 "external/foo/libstatic2",
2726 "external/foo/libshared1",
2727 "external/foo/libshared2",
2728 "external/foo/liblinux",
2729 "external/foo/libandroid",
2730 "external/foo/libarm",
2731 "external/foo/lib32",
2732 "external/foo/libandroid_arm",
2733 "defaults/cc/common/ndk_libc++_shared",
Liz Kammer08572c62021-09-30 10:11:04 -04002734 }
2735
2736 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2737 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2738
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002739 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002740 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002741 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002742
2743 lastIncludes := []string{
2744 "out/soong/ndk/sysroot/usr/include",
2745 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
2746 }
2747
2748 combineSlices := func(slices ...[]string) []string {
2749 var ret []string
2750 for _, s := range slices {
2751 ret = append(ret, s...)
2752 }
2753 return ret
2754 }
2755
2756 testCases := []struct {
2757 name string
2758 src string
2759 expected []string
2760 }{
2761 {
2762 name: "c",
2763 src: "foo.c",
Yi Kong13beeed2023-07-15 03:09:00 +09002764 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002765 },
2766 {
2767 name: "cc",
2768 src: "foo.cc",
Yi Kong13beeed2023-07-15 03:09:00 +09002769 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002770 },
2771 {
2772 name: "assemble",
2773 src: "foo.s",
Yi Kong13beeed2023-07-15 03:09:00 +09002774 expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
Liz Kammer08572c62021-09-30 10:11:04 -04002775 },
2776 }
2777
2778 for _, tc := range testCases {
2779 t.Run(tc.name, func(t *testing.T) {
2780 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002781 cc_library {
2782 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002783 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002784 cflags: ["-std=candcpp"],
2785 conlyflags: ["-std=conly"],
2786 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002787 local_include_dirs: ["local_include_dirs"],
2788 export_include_dirs: ["export_include_dirs"],
2789 export_system_include_dirs: ["export_system_include_dirs"],
2790 static_libs: ["libstatic1", "libstatic2"],
2791 whole_static_libs: ["libwhole1", "libwhole2"],
2792 shared_libs: ["libshared1", "libshared2"],
2793 header_libs: ["libheader1", "libheader2"],
2794 target: {
2795 android: {
2796 shared_libs: ["libandroid"],
2797 local_include_dirs: ["android_local_include_dirs"],
2798 export_include_dirs: ["android_export_include_dirs"],
2799 },
2800 android_arm: {
2801 shared_libs: ["libandroid_arm"],
2802 local_include_dirs: ["android_arm_local_include_dirs"],
2803 export_include_dirs: ["android_arm_export_include_dirs"],
2804 },
2805 linux: {
2806 shared_libs: ["liblinux"],
2807 local_include_dirs: ["linux_local_include_dirs"],
2808 export_include_dirs: ["linux_export_include_dirs"],
2809 },
2810 },
2811 multilib: {
2812 lib32: {
2813 shared_libs: ["lib32"],
2814 local_include_dirs: ["lib32_local_include_dirs"],
2815 export_include_dirs: ["lib32_export_include_dirs"],
2816 },
2817 },
2818 arch: {
2819 arm: {
2820 shared_libs: ["libarm"],
2821 local_include_dirs: ["arm_local_include_dirs"],
2822 export_include_dirs: ["arm_export_include_dirs"],
2823 },
2824 },
2825 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002826 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002827 }
2828
2829 cc_library_headers {
2830 name: "libheader1",
2831 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002832 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002833 stl: "none",
2834 }
2835
2836 cc_library_headers {
2837 name: "libheader2",
2838 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002839 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002840 stl: "none",
2841 }
Liz Kammer08572c62021-09-30 10:11:04 -04002842 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002843
Liz Kammer08572c62021-09-30 10:11:04 -04002844 libs := []string{
2845 "libstatic1",
2846 "libstatic2",
2847 "libwhole1",
2848 "libwhole2",
2849 "libshared1",
2850 "libshared2",
2851 "libandroid",
2852 "libandroid_arm",
2853 "liblinux",
2854 "lib32",
2855 "libarm",
2856 }
Colin Crossae628182021-06-14 16:52:28 -07002857
Liz Kammer08572c62021-09-30 10:11:04 -04002858 for _, lib := range libs {
2859 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002860 cc_library {
2861 name: "%s",
2862 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002863 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002864 stl: "none",
2865 }
2866 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002867 }
2868
2869 ctx := android.GroupFixturePreparers(
2870 PrepareForIntegrationTestWithCc,
2871 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2872 ).RunTest(t)
2873 // Use the arm variant instead of the arm64 variant so that it gets headers from
2874 // ndk_libandroid_support to test LateStaticLibs.
2875 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
2876
2877 var includes []string
2878 flags := strings.Split(cflags, " ")
2879 for _, flag := range flags {
2880 if strings.HasPrefix(flag, "-I") {
2881 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2882 } else if flag == "-isystem" {
2883 // skip isystem, include next
2884 } else if len(flag) > 0 {
2885 includes = append(includes, flag)
2886 }
2887 }
2888
2889 android.AssertArrayString(t, "includes", tc.expected, includes)
2890 })
Colin Crossae628182021-06-14 16:52:28 -07002891 }
2892
Colin Crossae628182021-06-14 16:52:28 -07002893}
Alixb5f6d9e2022-04-20 23:00:58 +00002894
zijunzhao933e3802023-01-12 07:26:20 +00002895func TestAddnoOverride64GlobalCflags(t *testing.T) {
2896 t.Parallel()
2897 ctx := testCc(t, `
2898 cc_library_shared {
2899 name: "libclient",
2900 srcs: ["foo.c"],
2901 shared_libs: ["libfoo#1"],
2902 }
2903
2904 cc_library_shared {
2905 name: "libfoo",
2906 srcs: ["foo.c"],
2907 shared_libs: ["libbar"],
2908 export_shared_lib_headers: ["libbar"],
2909 stubs: {
2910 symbol_file: "foo.map.txt",
2911 versions: ["1", "2", "3"],
2912 },
2913 }
2914
2915 cc_library_shared {
2916 name: "libbar",
2917 export_include_dirs: ["include/libbar"],
2918 srcs: ["foo.c"],
2919 }`)
2920
2921 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2922
2923 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2924 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2925 }
2926}
2927
Alixb5f6d9e2022-04-20 23:00:58 +00002928func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002929 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002930 tests := []struct {
2931 name string
2932 clang bool
2933 BuildBrokenClangProperty bool
2934 err string
2935 }{
2936 {
2937 name: "error when clang is set to false",
2938 clang: false,
2939 err: "is no longer supported",
2940 },
2941 {
2942 name: "error when clang is set to true",
2943 clang: true,
2944 err: "property is deprecated, see Changes.md",
2945 },
2946 {
2947 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2948 clang: true,
2949 BuildBrokenClangProperty: true,
2950 },
2951 }
2952
2953 for _, test := range tests {
2954 t.Run(test.name, func(t *testing.T) {
2955 bp := fmt.Sprintf(`
2956 cc_library {
2957 name: "foo",
2958 clang: %t,
2959 }`, test.clang)
2960
2961 if test.err == "" {
2962 android.GroupFixturePreparers(
2963 prepareForCcTest,
2964 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2965 if test.BuildBrokenClangProperty {
2966 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
2967 }
2968 }),
2969 ).RunTestWithBp(t, bp)
2970 } else {
2971 prepareForCcTest.
2972 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
2973 RunTestWithBp(t, bp)
2974 }
2975 })
2976 }
2977}
Alix Espinoef47e542022-09-14 19:10:51 +00002978
2979func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002980 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00002981 tests := []struct {
2982 name string
2983 clangAsFlags []string
2984 BuildBrokenClangAsFlags bool
2985 err string
2986 }{
2987 {
2988 name: "error when clang_asflags is set",
2989 clangAsFlags: []string{"-a", "-b"},
2990 err: "clang_asflags: property is deprecated",
2991 },
2992 {
2993 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
2994 clangAsFlags: []string{"-a", "-b"},
2995 BuildBrokenClangAsFlags: true,
2996 },
2997 }
2998
2999 for _, test := range tests {
3000 t.Run(test.name, func(t *testing.T) {
3001 bp := fmt.Sprintf(`
3002 cc_library {
3003 name: "foo",
3004 clang_asflags: %s,
3005 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3006
3007 if test.err == "" {
3008 android.GroupFixturePreparers(
3009 prepareForCcTest,
3010 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3011 if test.BuildBrokenClangAsFlags {
3012 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3013 }
3014 }),
3015 ).RunTestWithBp(t, bp)
3016 } else {
3017 prepareForCcTest.
3018 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3019 RunTestWithBp(t, bp)
3020 }
3021 })
3022 }
3023}
3024
3025func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003026 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003027 tests := []struct {
3028 name string
3029 clangCFlags []string
3030 BuildBrokenClangCFlags bool
3031 err string
3032 }{
3033 {
3034 name: "error when clang_cflags is set",
3035 clangCFlags: []string{"-a", "-b"},
3036 err: "clang_cflags: property is deprecated",
3037 },
3038 {
3039 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3040 clangCFlags: []string{"-a", "-b"},
3041 BuildBrokenClangCFlags: true,
3042 },
3043 }
3044
3045 for _, test := range tests {
3046 t.Run(test.name, func(t *testing.T) {
3047 bp := fmt.Sprintf(`
3048 cc_library {
3049 name: "foo",
3050 clang_cflags: %s,
3051 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3052
3053 if test.err == "" {
3054 android.GroupFixturePreparers(
3055 prepareForCcTest,
3056 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3057 if test.BuildBrokenClangCFlags {
3058 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3059 }
3060 }),
3061 ).RunTestWithBp(t, bp)
3062 } else {
3063 prepareForCcTest.
3064 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3065 RunTestWithBp(t, bp)
3066 }
3067 })
3068 }
3069}
Wei Li5f5d2712023-12-11 15:40:29 -08003070
3071func TestStrippedAllOutputFile(t *testing.T) {
3072 t.Parallel()
3073 bp := `
3074 cc_library {
3075 name: "test_lib",
3076 srcs: ["test_lib.cpp"],
3077 dist: {
3078 targets: [ "dist_target" ],
3079 tag: "stripped_all",
3080 }
3081 }
3082 `
3083 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3084 ctx := testCcWithConfig(t, config)
3085 module := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared").Module()
3086 outputFile, err := module.(android.OutputFileProducer).OutputFiles("stripped_all")
3087 if err != nil {
3088 t.Errorf("Expected cc_library to produce output files, error: %s", err)
3089 return
3090 }
3091 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3092 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3093 return
3094 }
3095}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003096
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003097func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003098 t.Parallel()
3099
3100 bp := `
3101 cc_binary {
3102 name: "binfoo",
3103 srcs: ["binfoo.cc"],
3104 vendor_available: true,
3105 product_available: true,
3106 shared_libs: ["libbar"]
3107 }
3108 cc_library {
3109 name: "libbar",
3110 srcs: ["libbar.cc"],
3111 vendor_available: true,
3112 product_available: true,
3113 }
3114 `
3115
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003116 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003117
3118 hasDep := func(m android.Module, wantDep android.Module) bool {
3119 t.Helper()
3120 var found bool
3121 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3122 if dep == wantDep {
3123 found = true
3124 }
3125 })
3126 return found
3127 }
3128
3129 testDepWithVariant := func(imageVariant string) {
3130 imageVariantStr := ""
3131 if imageVariant != "core" {
3132 imageVariantStr = "_" + imageVariant
3133 }
3134 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3135 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3136 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3137 }
3138
3139 testDepWithVariant("core")
3140 testDepWithVariant("vendor")
3141 testDepWithVariant("product")
3142}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003143
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003144func TestVendorSdkVersion(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003145 t.Parallel()
3146
3147 bp := `
3148 cc_library {
3149 name: "libfoo",
3150 srcs: ["libfoo.cc"],
3151 vendor_available: true,
3152 }
3153
3154 cc_library {
3155 name: "libbar",
3156 srcs: ["libbar.cc"],
3157 vendor_available: true,
3158 min_sdk_version: "29",
3159 }
3160 `
3161
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003162 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003163 testSdkVersionFlag := func(module, version string) {
3164 flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3165 android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
3166 }
3167
3168 testSdkVersionFlag("libfoo", "10000")
3169 testSdkVersionFlag("libbar", "29")
3170
3171 ctx = android.GroupFixturePreparers(
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003172 prepareForCcTest,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003173 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3174 if variables.BuildFlags == nil {
3175 variables.BuildFlags = make(map[string]string)
3176 }
3177 variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
3178 }),
3179 ).RunTestWithBp(t, bp)
3180 testSdkVersionFlag("libfoo", "30")
3181 testSdkVersionFlag("libbar", "29")
3182}