blob: a479cb30e49d5a00343bee237c688620ced50cba [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) {
Colin Crossd27205e2024-09-12 22:41:37 -070052 ctx.Transition("apex", &testApexTransitionMutator{})
Yu Liue4312402023-01-18 09:15:31 -080053 })
54}
55
Colin Crossd27205e2024-09-12 22:41:37 -070056type testApexTransitionMutator struct{}
57
58func (t *testApexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
59 return []string{apexVariationName}
60}
61
62func (t *testApexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
63 return sourceVariation
64}
65
66func (t *testApexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
67 return incomingVariation
68}
69
70func (t *testApexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
Yu Liue4312402023-01-18 09:15:31 -080071 apexInfo := android.ApexInfo{
72 ApexVariationName: apexVariationName,
73 MinSdkVersion: android.ApiLevelForTest(apexVersion),
74 }
Colin Crossd27205e2024-09-12 22:41:37 -070075 android.SetProvider(ctx, android.ApexInfoProvider, apexInfo)
Yu Liue4312402023-01-18 09:15:31 -080076}
77
Paul Duffin8567f222021-03-23 00:02:06 +000078// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000079//
80// See testCc for an explanation as to how to stop using this deprecated method.
81//
82// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080083func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070084 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000085 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000086 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090087}
88
Paul Duffin8567f222021-03-23 00:02:06 +000089// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000090//
Paul Duffin8567f222021-03-23 00:02:06 +000091// 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 +000092// easier to customize the test behavior.
93//
94// 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 +000095// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000096// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
97// that it did not change the test behavior unexpectedly.
98//
99// deprecated
Logan Chienf3511742017-10-31 18:04:35 +0800100func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800101 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +0000102 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +0000103 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +0800104}
105
Paul Duffin8567f222021-03-23 00:02:06 +0000106// testCcErrorWithConfig 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 testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800112 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800113
Paul Duffin8567f222021-03-23 00:02:06 +0000114 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000115 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
116 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800117}
118
Paul Duffin8567f222021-03-23 00:02:06 +0000119// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000120//
121// See testCc for an explanation as to how to stop using this deprecated method.
122//
123// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900124func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900125 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000126 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900127 testCcErrorWithConfig(t, pattern, config)
128 return
129}
130
Logan Chienf3511742017-10-31 18:04:35 +0800131const (
Colin Cross7113d202019-11-20 16:39:12 -0800132 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900133 vendorVariant = "android_vendor_arm64_armv8-a_shared"
134 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800135 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800136)
137
Paul Duffindb462dd2021-03-21 22:01:55 +0000138// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
139// running it in a fixture that requires all source files to exist.
140func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
141 android.GroupFixturePreparers(
142 PrepareForTestWithCcDefaultModules,
143 android.PrepareForTestDisallowNonExistentPaths,
144 ).RunTest(t)
145}
146
Jiyong Park6a43f042017-10-12 23:05:00 +0900147func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400148 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900149 ctx := testCc(t, `
150 cc_library {
151 name: "libTest",
152 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700153 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800154 nocrt: true,
155 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900156 vendor_available: true,
157 target: {
158 vendor: {
159 srcs: ["bar.c"],
160 },
161 },
162 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900163 `)
164
Logan Chienf3511742017-10-31 18:04:35 +0800165 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900166 var objs []string
167 for _, o := range ld.Inputs {
168 objs = append(objs, o.Base())
169 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800170 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900171 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
172 }
173}
174
Justin Yun7f99ec72021-04-12 13:19:28 +0900175func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
176 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
177 partitionDefined := false
178 checkPartition := func(specific bool, partition string) {
179 if specific {
180 if expected != partition && !partitionDefined {
181 // The variant is installed to the 'partition'
182 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
183 }
184 partitionDefined = true
185 } else {
186 // The variant is not installed to the 'partition'
187 if expected == partition {
188 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
189 }
190 }
191 }
192 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800193 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900194 }
195 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800196 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900197 }
198 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800199 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900200 }
201 systemExtSpecific := func(m *Module) bool {
202 return m.SystemExtSpecific()
203 }
204 checkPartition(socSpecific(mod), "vendor")
205 checkPartition(deviceSpecific(mod), "odm")
206 checkPartition(productSpecific(mod), "product")
207 checkPartition(systemExtSpecific(mod), "system_ext")
208 if !partitionDefined && expected != "system" {
209 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
210 " but installed to system partition", variant, name, expected)
211 }
212}
213
214func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400215 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900216 t.Helper()
217 ctx := prepareForCcTest.RunTestWithBp(t, `
218 cc_library {
219 name: "libsystem",
220 }
221 cc_library {
222 name: "libsystem_ext",
223 system_ext_specific: true,
224 }
225 cc_library {
226 name: "libproduct",
227 product_specific: true,
228 }
229 cc_library {
230 name: "libvendor",
231 vendor: true,
232 }
233 cc_library {
234 name: "libodm",
235 device_specific: true,
236 }
237 cc_library {
238 name: "liball_available",
239 vendor_available: true,
240 product_available: true,
241 }
242 cc_library {
243 name: "libsystem_ext_all_available",
244 system_ext_specific: true,
245 vendor_available: true,
246 product_available: true,
247 }
248 cc_library {
249 name: "liball_available_odm",
250 odm_available: true,
251 product_available: true,
252 }
253 cc_library {
254 name: "libproduct_vendoravailable",
255 product_specific: true,
256 vendor_available: true,
257 }
258 cc_library {
259 name: "libproduct_odmavailable",
260 product_specific: true,
261 odm_available: true,
262 }
263 `).TestContext
264
265 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
266 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
267 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
268 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
269 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
270
271 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
272 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
273 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
274
275 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
276 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
277 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
278
279 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
280 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
281 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
282
283 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
284 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
285
286 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
287 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
288}
289
Colin Crossf61d03d2023-11-02 16:56:39 -0700290func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900291 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700292 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800293 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900294 assertArrayString(t, actual, expected)
295}
296
Chris Parsons79d66a52020-06-05 17:26:16 -0400297func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400298 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400299 bp := `
300 cc_test_library {
301 name: "test_lib",
302 srcs: ["test_lib.cpp"],
303 gtest: false,
304 }
305
306 cc_test {
307 name: "main_test",
308 data_libs: ["test_lib"],
309 gtest: false,
310 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400311 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400312
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000313 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400314
315 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700316 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
317 testBinary := testingModule.Module().(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000318 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons79d66a52020-06-05 17:26:16 -0400319 if len(outputFiles) != 1 {
320 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
321 return
322 }
323 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800324 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400325 return
326 }
327
328 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400329 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400330
331 if !strings.HasSuffix(outputPath, "/main_test") {
332 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
333 return
334 }
335 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
336 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
337 return
338 }
339}
340
Chris Parsons216e10a2020-07-09 17:12:52 -0400341func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400342 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400343 bp := `
344 cc_test_library {
345 name: "test_lib",
346 srcs: ["test_lib.cpp"],
347 relative_install_path: "foo/bar/baz",
348 gtest: false,
349 }
350
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400351 cc_binary {
352 name: "test_bin",
353 relative_install_path: "foo/bar/baz",
354 compile_multilib: "both",
355 }
356
Chris Parsons216e10a2020-07-09 17:12:52 -0400357 cc_test {
358 name: "main_test",
359 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400360 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400361 gtest: false,
362 }
363 `
364
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000365 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400366
367 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700368 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
369 module := testingModule.Module()
Chris Parsons216e10a2020-07-09 17:12:52 -0400370 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000371 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons216e10a2020-07-09 17:12:52 -0400372 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400373 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400374 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400375 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800376 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400377 }
378
379 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400380
381 if !strings.HasSuffix(outputPath, "/main_test") {
382 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
383 }
Colin Crossaa255532020-07-03 13:18:24 -0700384 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons216e10a2020-07-09 17:12:52 -0400385 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
386 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400387 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400388 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400389 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
390 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
391 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
392 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400393}
394
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000395func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400396 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000397 bp := `
398 cc_test {
399 name: "main_test",
400 srcs: ["main_test.cpp"],
401 test_suites: [
402 "suite_1",
403 "suite_2",
404 ],
405 gtest: false,
406 }
407 `
408
409 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
410 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
411
412 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
413 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
414 if len(compatEntries) != 2 {
415 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
416 }
417 if compatEntries[0] != "suite_1" {
418 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
419 " but was '%s'", compatEntries[0])
420 }
421 if compatEntries[1] != "suite_2" {
422 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
423 " but was '%s'", compatEntries[1])
424 }
425}
426
427func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400428 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000429 bp := `
430 cc_test_library {
431 name: "main_test_lib",
432 srcs: ["main_test_lib.cpp"],
433 test_suites: [
434 "suite_1",
435 "suite_2",
436 ],
437 gtest: false,
438 }
439 `
440
441 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
442 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
443
444 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
445 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
446 if len(compatEntries) != 2 {
447 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
448 }
449 if compatEntries[0] != "suite_1" {
450 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
451 " but was '%s'", compatEntries[0])
452 }
453 if compatEntries[1] != "suite_2" {
454 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
455 " but was '%s'", compatEntries[1])
456 }
457}
458
Jooyung Hana70f0672019-01-18 15:20:43 +0900459func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400460 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900461 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900462 testCc(t, `
463 cc_library {
464 name: "libllndk",
465 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700466 llndk: {
467 symbol_file: "libllndk.map.txt",
468 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900469 }
470
471 cc_library {
472 name: "libdoubleloadable",
473 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900474 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900475 double_loadable: true,
476 }
477 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900478 // okay to link : double_loadable -> double_loadable
479 testCc(t, `
480 cc_library {
481 name: "libdoubleloadable1",
482 shared_libs: ["libdoubleloadable2"],
483 vendor_available: true,
484 double_loadable: true,
485 }
486
487 cc_library {
488 name: "libdoubleloadable2",
489 vendor_available: true,
490 double_loadable: true,
491 }
492 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900493 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900494 testCc(t, `
495 cc_library {
496 name: "libdoubleloadable",
497 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900498 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900499 double_loadable: true,
500 shared_libs: ["libnondoubleloadable"],
501 }
502
503 cc_library {
504 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900505 vendor_available: true,
506 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900507 double_loadable: true,
508 }
509 `)
510 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
511 testCc(t, `
512 cc_library {
513 name: "libllndk",
514 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700515 llndk: {
516 symbol_file: "libllndk.map.txt",
517 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900518 }
519
520 cc_library {
521 name: "libcoreonly",
522 shared_libs: ["libvendoravailable"],
523 }
524
525 // indirect dependency of LLNDK
526 cc_library {
527 name: "libvendoravailable",
528 vendor_available: true,
529 double_loadable: true,
530 }
531 `)
532}
533
534func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400535 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900536 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900537 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
538 cc_library {
539 name: "libllndk",
540 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700541 llndk: {
542 symbol_file: "libllndk.map.txt",
543 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900544 }
545
546 cc_library {
547 name: "libnondoubleloadable",
548 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900549 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900550 }
551 `)
552
553 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
554 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
555 cc_library {
556 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700557 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900558 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700559 llndk: {
560 symbol_file: "libllndk.map.txt",
561 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900562 }
563
564 cc_library {
565 name: "libnondoubleloadable",
566 vendor_available: true,
567 }
568 `)
569
Jooyung Hana70f0672019-01-18 15:20:43 +0900570 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
571 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
572 cc_library {
573 name: "libllndk",
574 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700575 llndk: {
576 symbol_file: "libllndk.map.txt",
577 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900578 }
579
580 cc_library {
581 name: "libcoreonly",
582 shared_libs: ["libvendoravailable"],
583 }
584
585 // indirect dependency of LLNDK
586 cc_library {
587 name: "libvendoravailable",
588 vendor_available: true,
589 }
590 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900591
592 // The error is not from 'client' but from 'libllndk'
593 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
594 cc_library {
595 name: "client",
596 vendor_available: true,
597 double_loadable: true,
598 shared_libs: ["libllndk"],
599 }
600 cc_library {
601 name: "libllndk",
602 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700603 llndk: {
604 symbol_file: "libllndk.map.txt",
605 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900606 }
607 cc_library {
608 name: "libnondoubleloadable",
609 vendor_available: true,
610 }
611 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800612}
613
Jooyung Han38002912019-05-16 04:01:54 +0900614func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400615 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800616 bp := `
617 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800618 name: "libvendor",
619 vendor: true,
620 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800621 vndk_prebuilt_shared {
622 name: "prevndk",
623 version: "27",
624 target_arch: "arm",
625 binder32bit: true,
626 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900627 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800628 vndk: {
629 enabled: true,
630 },
631 arch: {
632 arm: {
633 srcs: ["liba.so"],
634 },
635 },
636 }
637 cc_library {
638 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700639 llndk: {
640 symbol_file: "libllndk.map.txt",
641 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800642 }
643 cc_library {
644 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700645 llndk: {
646 symbol_file: "libllndkprivate.map.txt",
647 private: true,
648 }
Colin Cross78212242021-01-06 14:51:30 -0800649 }
Colin Cross78212242021-01-06 14:51:30 -0800650 llndk_libraries_txt {
651 name: "llndk.libraries.txt",
652 }
Colin Cross78212242021-01-06 14:51:30 -0800653 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800654
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000655 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900656 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800657 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900658
Colin Crossfb0c16e2019-11-20 17:12:35 -0800659 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900660
Jooyung Han38002912019-05-16 04:01:54 +0900661 tests := []struct {
662 variant string
663 name string
664 expected string
665 }{
Jooyung Han38002912019-05-16 04:01:54 +0900666 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800667 {vendorVariant, "libllndk", "native:vndk"},
Kiyoung Kim9f26fcf2024-05-27 17:25:52 +0900668 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +0900669 {coreVariant, "libllndk", "native:platform"},
670 }
671 for _, test := range tests {
672 t.Run(test.name, func(t *testing.T) {
673 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
674 assertString(t, module.makeLinkType, test.expected)
675 })
676 }
677}
678
Jeff Gaston294356f2017-09-27 17:05:30 -0700679var staticLinkDepOrderTestCases = []struct {
680 // This is a string representation of a map[moduleName][]moduleDependency .
681 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800682 inStatic string
683
684 // This is a string representation of a map[moduleName][]moduleDependency .
685 // It models the dependencies declared in an Android.bp file.
686 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700687
688 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
689 // The keys of allOrdered specify which modules we would like to check.
690 // The values of allOrdered specify the expected result (of the transitive closure of all
691 // dependencies) for each module to test
692 allOrdered string
693
694 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
695 // The keys of outOrdered specify which modules we would like to check.
696 // The values of outOrdered specify the expected result (of the ordered linker command line)
697 // for each module to test.
698 outOrdered string
699}{
700 // Simple tests
701 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800702 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700703 outOrdered: "",
704 },
705 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800706 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700707 outOrdered: "a:",
708 },
709 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800710 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700711 outOrdered: "a:b; b:",
712 },
713 // Tests of reordering
714 {
715 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800716 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700717 outOrdered: "a:b,c,d; b:d; c:d; d:",
718 },
719 {
720 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800721 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700722 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
723 },
724 {
725 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800726 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700727 outOrdered: "a:d,b,e,c; d:b; e:c",
728 },
729 {
730 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800731 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700732 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
733 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
734 },
735 {
736 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800737 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 -0700738 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
739 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
740 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800741 // shared dependencies
742 {
743 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
744 // So, we don't actually have to check that a shared dependency of c will change the order
745 // of a library that depends statically on b and on c. We only need to check that if c has
746 // a shared dependency on b, that that shows up in allOrdered.
747 inShared: "c:b",
748 allOrdered: "c:b",
749 outOrdered: "c:",
750 },
751 {
752 // This test doesn't actually include any shared dependencies but it's a reminder of what
753 // the second phase of the above test would look like
754 inStatic: "a:b,c; c:b",
755 allOrdered: "a:c,b; c:b",
756 outOrdered: "a:c,b; c:b",
757 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700758 // tiebreakers for when two modules specifying different orderings and there is no dependency
759 // to dictate an order
760 {
761 // 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 -0800762 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700763 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
764 },
765 {
766 // 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 -0800767 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 -0700768 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
769 },
770 // Tests involving duplicate dependencies
771 {
772 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800773 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700774 outOrdered: "a:c,b",
775 },
776 {
777 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800778 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700779 outOrdered: "a:d,c,b",
780 },
781 // Tests to confirm the nonexistence of infinite loops.
782 // These cases should never happen, so as long as the test terminates and the
783 // result is deterministic then that should be fine.
784 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800785 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700786 outOrdered: "a:a",
787 },
788 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800789 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700790 allOrdered: "a:b,c; b:c,a; c:a,b",
791 outOrdered: "a:b; b:c; c:a",
792 },
793 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800794 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700795 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
796 outOrdered: "a:c,b; b:a,c; c:b,a",
797 },
798}
799
800// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
801func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
802 // convert from "a:b,c; d:e" to "a:b,c;d:e"
803 strippedText := strings.Replace(text, " ", "", -1)
804 if len(strippedText) < 1 {
805 return []android.Path{}, make(map[android.Path][]android.Path, 0)
806 }
807 allDeps = make(map[android.Path][]android.Path, 0)
808
809 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
810 moduleTexts := strings.Split(strippedText, ";")
811
812 outputForModuleName := func(moduleName string) android.Path {
813 return android.PathForTesting(moduleName)
814 }
815
816 for _, moduleText := range moduleTexts {
817 // convert from "a:b,c" to ["a", "b,c"]
818 components := strings.Split(moduleText, ":")
819 if len(components) != 2 {
820 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
821 }
822 moduleName := components[0]
823 moduleOutput := outputForModuleName(moduleName)
824 modulesInOrder = append(modulesInOrder, moduleOutput)
825
826 depString := components[1]
827 // convert from "b,c" to ["b", "c"]
828 depNames := strings.Split(depString, ",")
829 if len(depString) < 1 {
830 depNames = []string{}
831 }
832 var deps []android.Path
833 for _, depName := range depNames {
834 deps = append(deps, outputForModuleName(depName))
835 }
836 allDeps[moduleOutput] = deps
837 }
838 return modulesInOrder, allDeps
839}
840
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800841func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400842 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700843 ctx := testCc(t, `
844 cc_library {
845 name: "a",
846 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900847 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700848 }
849 cc_library {
850 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900851 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700852 }
853 cc_library {
854 name: "c",
855 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900856 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700857 }
858 cc_library {
859 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900860 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700861 }
862
863 `)
864
Colin Cross7113d202019-11-20 16:39:12 -0800865 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700866 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000867 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800868 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400869 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700870
871 if !reflect.DeepEqual(actual, expected) {
872 t.Errorf("staticDeps orderings were not propagated correctly"+
873 "\nactual: %v"+
874 "\nexpected: %v",
875 actual,
876 expected,
877 )
878 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900879}
Jeff Gaston294356f2017-09-27 17:05:30 -0700880
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800881func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400882 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800883 ctx := testCc(t, `
884 cc_library {
885 name: "a",
886 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900887 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800888 }
889 cc_library {
890 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900891 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800892 }
893 cc_library {
894 name: "c",
895 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900896 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800897 }
898
899 `)
900
Colin Cross7113d202019-11-20 16:39:12 -0800901 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800902 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000903 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800904 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400905 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800906
907 if !reflect.DeepEqual(actual, expected) {
908 t.Errorf("staticDeps orderings did not account for shared libs"+
909 "\nactual: %v"+
910 "\nexpected: %v",
911 actual,
912 expected,
913 )
914 }
915}
916
Jooyung Hanb04a4992020-03-13 18:57:35 +0900917func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700918 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900919 if !reflect.DeepEqual(actual, expected) {
920 t.Errorf(message+
921 "\nactual: %v"+
922 "\nexpected: %v",
923 actual,
924 expected,
925 )
926 }
927}
928
Jooyung Han61b66e92020-03-21 14:21:46 +0000929func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400930 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800931 result := prepareForCcTest.RunTestWithBp(t, `
932 cc_library {
933 name: "libllndk",
934 stubs: { versions: ["1", "2"] },
935 llndk: {
936 symbol_file: "libllndk.map.txt",
937 },
938 export_include_dirs: ["include"],
939 }
940
941 cc_prebuilt_library_shared {
942 name: "libllndkprebuilt",
Spandan Das357ffcc2024-07-24 18:07:48 +0000943 stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" },
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800944 llndk: {
945 symbol_file: "libllndkprebuilt.map.txt",
946 },
947 }
948
949 cc_library {
950 name: "libllndk_with_external_headers",
951 stubs: { versions: ["1", "2"] },
952 llndk: {
953 symbol_file: "libllndk.map.txt",
954 export_llndk_headers: ["libexternal_llndk_headers"],
955 },
956 header_libs: ["libexternal_headers"],
957 export_header_lib_headers: ["libexternal_headers"],
958 }
959 cc_library_headers {
960 name: "libexternal_headers",
961 export_include_dirs: ["include"],
962 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900963 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800964 }
965 cc_library_headers {
966 name: "libexternal_llndk_headers",
967 export_include_dirs: ["include_llndk"],
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800968 export_system_include_dirs: ["include_system_llndk"],
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800969 llndk: {
970 symbol_file: "libllndk.map.txt",
971 },
972 vendor_available: true,
973 }
974
975 cc_library {
976 name: "libllndk_with_override_headers",
977 stubs: { versions: ["1", "2"] },
978 llndk: {
979 symbol_file: "libllndk.map.txt",
980 override_export_include_dirs: ["include_llndk"],
981 },
982 export_include_dirs: ["include"],
983 }
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800984
985 cc_library {
986 name: "libllndk_with_system_headers",
987 llndk: {
988 symbol_file: "libllndk.map.txt",
989 export_llndk_headers: ["libexternal_llndk_headers"],
990 export_headers_as_system: true,
991 },
992 export_include_dirs: ["include"],
993 export_system_include_dirs: ["include_system"],
994 }
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800995 `)
996 actual := result.ModuleVariantsForTests("libllndk")
997 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900998 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800999 actual = append(actual[:i], actual[i+1:]...)
1000 i--
1001 }
1002 }
1003 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001004 "android_vendor_arm64_armv8-a_shared",
1005 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001006 }
1007 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
1008
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001009 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Han33eb6152024-03-11 15:46:48 +09001010 android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001011
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001012 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001013 t.Helper()
1014 m := result.ModuleForTests(module, variant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001015 f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001016 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1017 expectedDirs, f.IncludeDirs)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001018 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1019 expectedSystemDirs, f.SystemIncludeDirs)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001020 }
1021
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001022 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
1023 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
1024 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
1025 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
1026 []string{"include_system_llndk"}, "include_llndk")
1027 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
1028 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
1029 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
1030 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
1031 []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001032
1033 checkAbiLinkerIncludeDirs := func(module string) {
1034 t.Helper()
1035 coreModule := result.ModuleForTests(module, coreVariant)
1036 abiCheckFlags := ""
1037 for _, output := range coreModule.AllOutputs() {
1038 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1039 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1040 }
1041 }
1042 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001043 vendorInfo, _ := android.OtherModuleProvider(result, vendorModule, FlagExporterInfoProvider)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001044 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001045 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001046 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001047 }
1048 checkAbiLinkerIncludeDirs("libllndk")
1049 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1050 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001051 checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001052}
1053
Jiyong Parka46a4d52017-12-14 19:54:34 +09001054func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001055 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001056 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001057 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001058 name: "libllndk_headers",
1059 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001060 llndk: {
1061 llndk_headers: true,
1062 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001063 }
1064 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001065 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001066 llndk: {
1067 symbol_file: "libllndk.map.txt",
1068 export_llndk_headers: ["libllndk_headers"],
1069 }
Colin Cross0477b422020-10-13 18:43:54 -07001070 }
1071
1072 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001073 name: "libvendor",
1074 shared_libs: ["libllndk"],
1075 vendor: true,
1076 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001077 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001078 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001079 }
1080 `)
1081
1082 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001083 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001084 cflags := cc.Args["cFlags"]
1085 if !strings.Contains(cflags, "-Imy_include") {
1086 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1087 }
1088}
1089
Logan Chien43d34c32017-12-20 01:17:32 +08001090func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1091 actual := module.Properties.AndroidMkRuntimeLibs
1092 if !reflect.DeepEqual(actual, expected) {
1093 t.Errorf("incorrect runtime_libs for shared libs"+
1094 "\nactual: %v"+
1095 "\nexpected: %v",
1096 actual,
1097 expected,
1098 )
1099 }
1100}
1101
1102const runtimeLibAndroidBp = `
1103 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001104 name: "liball_available",
1105 vendor_available: true,
1106 product_available: true,
1107 no_libcrt : true,
1108 nocrt : true,
1109 system_shared_libs : [],
1110 }
1111 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001112 name: "libvendor_available1",
1113 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001114 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001115 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001116 nocrt : true,
1117 system_shared_libs : [],
1118 }
1119 cc_library {
1120 name: "libvendor_available2",
1121 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001122 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001123 target: {
1124 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001125 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001126 }
1127 },
Yi Konge7fe9912019-06-02 00:53:50 -07001128 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001129 nocrt : true,
1130 system_shared_libs : [],
1131 }
1132 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001133 name: "libproduct_vendor",
1134 product_specific: true,
1135 vendor_available: true,
1136 no_libcrt : true,
1137 nocrt : true,
1138 system_shared_libs : [],
1139 }
1140 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001141 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001142 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001143 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001144 nocrt : true,
1145 system_shared_libs : [],
1146 }
1147 cc_library {
1148 name: "libvendor1",
1149 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001150 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001151 nocrt : true,
1152 system_shared_libs : [],
1153 }
1154 cc_library {
1155 name: "libvendor2",
1156 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001157 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001158 no_libcrt : true,
1159 nocrt : true,
1160 system_shared_libs : [],
1161 }
1162 cc_library {
1163 name: "libproduct_available1",
1164 product_available: true,
1165 runtime_libs: ["liball_available"],
1166 no_libcrt : true,
1167 nocrt : true,
1168 system_shared_libs : [],
1169 }
1170 cc_library {
1171 name: "libproduct1",
1172 product_specific: true,
1173 no_libcrt : true,
1174 nocrt : true,
1175 system_shared_libs : [],
1176 }
1177 cc_library {
1178 name: "libproduct2",
1179 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001180 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001181 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001182 nocrt : true,
1183 system_shared_libs : [],
1184 }
1185`
1186
1187func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001188 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001189 ctx := testCc(t, runtimeLibAndroidBp)
1190
1191 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001192 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001193
Justin Yun8a2600c2020-12-07 12:44:03 +09001194 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1195 checkRuntimeLibs(t, []string{"liball_available"}, module)
1196
1197 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1198 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001199
1200 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001201 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001202
1203 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1204 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001205 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001206
Justin Yun8a2600c2020-12-07 12:44:03 +09001207 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1208 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001209
1210 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001211 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001212
1213 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1214 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001215 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001216
1217 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1218 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1219
1220 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001221 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001222}
1223
1224func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001225 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001226 ctx := testCc(t, runtimeLibAndroidBp)
1227
Colin Cross7113d202019-11-20 16:39:12 -08001228 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001229 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1230 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001231
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001232 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001233 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001234 checkRuntimeLibs(t, nil, module)
1235}
1236
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001237func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001238 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001239 actual := module.Properties.AndroidMkStaticLibs
1240 if !reflect.DeepEqual(actual, expected) {
1241 t.Errorf("incorrect static_libs"+
1242 "\nactual: %v"+
1243 "\nexpected: %v",
1244 actual,
1245 expected,
1246 )
1247 }
1248}
1249
1250const staticLibAndroidBp = `
1251 cc_library {
1252 name: "lib1",
1253 }
1254 cc_library {
1255 name: "lib2",
1256 static_libs: ["lib1"],
1257 }
1258`
1259
1260func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001261 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001262 ctx := testCc(t, staticLibAndroidBp)
1263
1264 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001265 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001266 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001267 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001268
1269 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001270 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001271 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1272 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001273 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001274}
1275
Jiyong Parkd08b6972017-09-26 10:50:54 +09001276var compilerFlagsTestCases = []struct {
1277 in string
1278 out bool
1279}{
1280 {
1281 in: "a",
1282 out: false,
1283 },
1284 {
1285 in: "-a",
1286 out: true,
1287 },
1288 {
1289 in: "-Ipath/to/something",
1290 out: false,
1291 },
1292 {
1293 in: "-isystempath/to/something",
1294 out: false,
1295 },
1296 {
1297 in: "--coverage",
1298 out: false,
1299 },
1300 {
1301 in: "-include a/b",
1302 out: true,
1303 },
1304 {
1305 in: "-include a/b c/d",
1306 out: false,
1307 },
1308 {
1309 in: "-DMACRO",
1310 out: true,
1311 },
1312 {
1313 in: "-DMAC RO",
1314 out: false,
1315 },
1316 {
1317 in: "-a -b",
1318 out: false,
1319 },
1320 {
1321 in: "-DMACRO=definition",
1322 out: true,
1323 },
1324 {
1325 in: "-DMACRO=defi nition",
1326 out: true, // TODO(jiyong): this should be false
1327 },
1328 {
1329 in: "-DMACRO(x)=x + 1",
1330 out: true,
1331 },
1332 {
1333 in: "-DMACRO=\"defi nition\"",
1334 out: true,
1335 },
1336}
1337
1338type mockContext struct {
1339 BaseModuleContext
1340 result bool
1341}
1342
1343func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1344 // CheckBadCompilerFlags calls this function when the flag should be rejected
1345 ctx.result = false
1346}
1347
1348func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001349 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001350 for _, testCase := range compilerFlagsTestCases {
1351 ctx := &mockContext{result: true}
1352 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1353 if ctx.result != testCase.out {
1354 t.Errorf("incorrect output:")
1355 t.Errorf(" input: %#v", testCase.in)
1356 t.Errorf(" expected: %#v", testCase.out)
1357 t.Errorf(" got: %#v", ctx.result)
1358 }
1359 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001360}
Jiyong Park374510b2018-03-19 18:23:01 +09001361
Jiyong Park37b25202018-07-11 10:49:27 +09001362func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001363 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001364 ctx := testCc(t, `
1365 cc_library_shared {
1366 name: "librecovery",
1367 recovery: true,
1368 }
1369 cc_library_shared {
1370 name: "librecovery32",
1371 recovery: true,
1372 compile_multilib:"32",
1373 }
Jiyong Park5baac542018-08-28 09:55:37 +09001374 cc_library_shared {
1375 name: "libHalInRecovery",
1376 recovery_available: true,
1377 vendor: true,
1378 }
Jiyong Park37b25202018-07-11 10:49:27 +09001379 `)
1380
1381 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001382 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001383 if len(variants) != 1 || !android.InList(arm64, variants) {
1384 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1385 }
1386
1387 variants = ctx.ModuleVariantsForTests("librecovery32")
1388 if android.InList(arm64, variants) {
1389 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1390 }
Jiyong Park5baac542018-08-28 09:55:37 +09001391
1392 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1393 if !recoveryModule.Platform() {
1394 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1395 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001396}
Jiyong Park5baac542018-08-28 09:55:37 +09001397
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001398func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001399 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001400 bp := `
1401 cc_prebuilt_test_library_shared {
1402 name: "test_lib",
1403 relative_install_path: "foo/bar/baz",
1404 srcs: ["srcpath/dontusethispath/baz.so"],
1405 }
1406
1407 cc_test {
1408 name: "main_test",
1409 data_libs: ["test_lib"],
1410 gtest: false,
1411 }
1412 `
1413
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001414 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001415
1416 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07001417 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
1418 module := testingModule.Module()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001419 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +00001420 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001421 if len(outputFiles) != 1 {
1422 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1423 }
1424 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001425 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001426 }
1427
1428 outputPath := outputFiles[0].String()
1429
1430 if !strings.HasSuffix(outputPath, "/main_test") {
1431 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1432 }
Colin Crossaa255532020-07-03 13:18:24 -07001433 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001434 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1435 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1436 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1437 }
1438}
1439
Jiyong Park7ed9de32018-10-15 22:25:07 +09001440func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001441 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001442 ctx := testCc(t, `
1443 cc_library_shared {
1444 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001445 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001446 stubs: {
1447 symbol_file: "foo.map.txt",
1448 versions: ["1", "2", "3"],
1449 },
1450 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001451
Jiyong Park7ed9de32018-10-15 22:25:07 +09001452 cc_library_shared {
1453 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001454 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001455 shared_libs: ["libFoo#1"],
1456 }`)
1457
1458 variants := ctx.ModuleVariantsForTests("libFoo")
1459 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001460 "android_arm64_armv8-a_shared",
1461 "android_arm64_armv8-a_shared_1",
1462 "android_arm64_armv8-a_shared_2",
1463 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001464 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001465 "android_arm_armv7-a-neon_shared",
1466 "android_arm_armv7-a-neon_shared_1",
1467 "android_arm_armv7-a-neon_shared_2",
1468 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001469 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001470 }
1471 variantsMismatch := false
1472 if len(variants) != len(expectedVariants) {
1473 variantsMismatch = true
1474 } else {
1475 for _, v := range expectedVariants {
1476 if !inList(v, variants) {
1477 variantsMismatch = false
1478 }
1479 }
1480 }
1481 if variantsMismatch {
1482 t.Errorf("variants of libFoo expected:\n")
1483 for _, v := range expectedVariants {
1484 t.Errorf("%q\n", v)
1485 }
1486 t.Errorf(", but got:\n")
1487 for _, v := range variants {
1488 t.Errorf("%q\n", v)
1489 }
1490 }
1491
Colin Cross7113d202019-11-20 16:39:12 -08001492 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001493 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001494 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001495 if !strings.Contains(libFlags, libFoo1StubPath) {
1496 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1497 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001498
Colin Cross7113d202019-11-20 16:39:12 -08001499 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001500 cFlags := libBarCompileRule.Args["cFlags"]
1501 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1502 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1503 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1504 }
Jiyong Park37b25202018-07-11 10:49:27 +09001505}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001506
Liz Kammer48cdbeb2023-03-17 10:17:50 -04001507func TestStubsForLibraryInMultipleApexes(t *testing.T) {
1508 t.Parallel()
1509 ctx := testCc(t, `
1510 cc_library_shared {
1511 name: "libFoo",
1512 srcs: ["foo.c"],
1513 stubs: {
1514 symbol_file: "foo.map.txt",
1515 versions: ["current"],
1516 },
1517 apex_available: ["bar", "a1"],
1518 }
1519
1520 cc_library_shared {
1521 name: "libBar",
1522 srcs: ["bar.c"],
1523 shared_libs: ["libFoo"],
1524 apex_available: ["a1"],
1525 }
1526
1527 cc_library_shared {
1528 name: "libA1",
1529 srcs: ["a1.c"],
1530 shared_libs: ["libFoo"],
1531 apex_available: ["a1"],
1532 }
1533
1534 cc_library_shared {
1535 name: "libBarA1",
1536 srcs: ["bara1.c"],
1537 shared_libs: ["libFoo"],
1538 apex_available: ["bar", "a1"],
1539 }
1540
1541 cc_library_shared {
1542 name: "libAnyApex",
1543 srcs: ["anyApex.c"],
1544 shared_libs: ["libFoo"],
1545 apex_available: ["//apex_available:anyapex"],
1546 }
1547
1548 cc_library_shared {
1549 name: "libBaz",
1550 srcs: ["baz.c"],
1551 shared_libs: ["libFoo"],
1552 apex_available: ["baz"],
1553 }
1554
1555 cc_library_shared {
1556 name: "libQux",
1557 srcs: ["qux.c"],
1558 shared_libs: ["libFoo"],
1559 apex_available: ["qux", "bar"],
1560 }`)
1561
1562 variants := ctx.ModuleVariantsForTests("libFoo")
1563 expectedVariants := []string{
1564 "android_arm64_armv8-a_shared",
1565 "android_arm64_armv8-a_shared_current",
1566 "android_arm_armv7-a-neon_shared",
1567 "android_arm_armv7-a-neon_shared_current",
1568 }
1569 variantsMismatch := false
1570 if len(variants) != len(expectedVariants) {
1571 variantsMismatch = true
1572 } else {
1573 for _, v := range expectedVariants {
1574 if !inList(v, variants) {
1575 variantsMismatch = false
1576 }
1577 }
1578 }
1579 if variantsMismatch {
1580 t.Errorf("variants of libFoo expected:\n")
1581 for _, v := range expectedVariants {
1582 t.Errorf("%q\n", v)
1583 }
1584 t.Errorf(", but got:\n")
1585 for _, v := range variants {
1586 t.Errorf("%q\n", v)
1587 }
1588 }
1589
1590 linkAgainstFoo := []string{"libBarA1"}
1591 linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
1592
1593 libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
1594 for _, lib := range linkAgainstFoo {
1595 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1596 libFlags := libLinkRule.Args["libFlags"]
1597 if !strings.Contains(libFlags, libFooPath) {
1598 t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
1599 }
1600 }
1601
1602 libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
1603 for _, lib := range linkAgainstFooStubs {
1604 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1605 libFlags := libLinkRule.Args["libFlags"]
1606 if !strings.Contains(libFlags, libFooStubPath) {
1607 t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
1608 }
1609 }
1610}
1611
Jooyung Hanb04a4992020-03-13 18:57:35 +09001612func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001613 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001614 for _, tc := range []struct{ moduleName, expected string }{
1615 {"libc", "__LIBC_API__"},
1616 {"libfoo", "__LIBFOO_API__"},
1617 {"libfoo@1", "__LIBFOO_1_API__"},
1618 {"libfoo-v1", "__LIBFOO_V1_API__"},
1619 {"libfoo.v1", "__LIBFOO_V1_API__"},
1620 } {
1621 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1622 }
1623}
1624
Liz Kammer83cf81b2022-09-22 08:24:20 -04001625func pathsToBase(paths android.Paths) []string {
1626 var ret []string
1627 for _, p := range paths {
1628 ret = append(ret, p.Base())
1629 }
1630 return ret
1631}
1632
1633func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001634 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001635 ctx := testCc(t, `
1636 cc_library_static {
1637 name: "foo",
1638 srcs: ["foo.c"],
1639 }
1640
1641 cc_library_static {
1642 name: "bar",
1643 srcs: ["bar.c"],
1644 }
1645
1646 cc_library_shared {
1647 name: "qux",
1648 srcs: ["qux.c"],
1649 }
1650
1651 cc_library_static {
1652 name: "baz",
1653 srcs: ["baz.c"],
1654 static_libs: ["foo"],
1655 shared_libs: ["qux"],
1656 whole_static_libs: ["bar"],
1657 }`)
1658
1659 variant := "android_arm64_armv8-a_static"
1660 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1661
1662 // For static libraries, the object files of a whole static dep are included in the archive
1663 // directly
1664 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1665 t.Errorf("Expected input objects %q, got %q", w, g)
1666 }
1667
1668 // non whole static dependencies are not linked into the archive
1669 if len(arRule.Implicits) > 0 {
1670 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1671 }
1672}
1673
1674func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001675 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001676 ctx := testCc(t, `
1677 cc_library_static {
1678 name: "foo",
1679 srcs: ["foo.c"],
1680 }
1681
1682 cc_library_static {
1683 name: "bar",
1684 srcs: ["bar.c"],
1685 }
1686
1687 cc_library_shared {
1688 name: "qux",
1689 srcs: ["qux.c"],
1690 }
1691
1692 cc_library_shared {
1693 name: "baz",
1694 srcs: ["baz.c"],
1695 static_libs: ["foo"],
1696 shared_libs: ["qux"],
1697 whole_static_libs: ["bar"],
1698 }`)
1699
1700 variant := "android_arm64_armv8-a_shared"
1701 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1702 libFlags := linkRule.Args["libFlags"]
1703 // When dynamically linking, we expect static dependencies to be found on the command line
1704 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1705 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1706 }
1707 // When dynamically linking, we expect whole static dependencies to be found on the command line
1708 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1709 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1710 }
1711
1712 // When dynamically linking, we expect shared dependencies to be found on the command line
1713 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1714 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1715 }
1716
1717 // We should only have the objects from the shared library srcs, not the whole static dependencies
1718 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1719 t.Errorf("Expected input objects %q, got %q", w, g)
1720 }
1721}
1722
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001723func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001724 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001725 ctx := testCc(t, `
1726 cc_binary {
1727 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001728 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001729 static_executable: true,
1730 }`)
1731
Colin Cross7113d202019-11-20 16:39:12 -08001732 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001733 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1734 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001735 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001736 for _, lib := range systemStaticLibs {
1737 if !strings.Contains(libFlags, lib) {
1738 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1739 }
1740 }
1741 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1742 for _, lib := range systemSharedLibs {
1743 if strings.Contains(libFlags, lib) {
1744 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1745 }
1746 }
1747}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001748
1749func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001750 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001751 ctx := testCc(t, `
1752 cc_binary {
1753 name: "mybin",
1754 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001755 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001756 static_executable: true,
1757 stl: "none",
1758 }
1759
1760 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001761 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001762 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001763 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001764 stl: "none",
1765 }
1766
1767 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001768 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001769 srcs: ["foo.c"],
1770 stl: "none",
1771 stubs: {
1772 versions: ["1"],
1773 },
1774 }`)
1775
Colin Cross0de8a1e2020-09-18 14:15:30 -07001776 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1777 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001778 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001779
1780 if !reflect.DeepEqual(actual, expected) {
1781 t.Errorf("staticDeps orderings were not propagated correctly"+
1782 "\nactual: %v"+
1783 "\nexpected: %v",
1784 actual,
1785 expected,
1786 )
1787 }
1788}
Jooyung Han38002912019-05-16 04:01:54 +09001789
Jooyung Hand48f3c32019-08-23 11:18:57 +09001790func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001791 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001792 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1793 cc_library {
1794 name: "libA",
1795 srcs: ["foo.c"],
1796 shared_libs: ["libB"],
1797 stl: "none",
1798 }
1799
1800 cc_library {
1801 name: "libB",
1802 srcs: ["foo.c"],
1803 enabled: false,
1804 stl: "none",
1805 }
1806 `)
1807}
1808
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001809func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1810 bp := `
1811 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001812 name: "test_afl_fuzz_target",
1813 srcs: ["foo.c"],
1814 host_supported: true,
1815 static_libs: [
1816 "afl_fuzz_static_lib",
1817 ],
1818 shared_libs: [
1819 "afl_fuzz_shared_lib",
1820 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001821 fuzzing_frameworks: {
1822 afl: true,
1823 libfuzzer: false,
1824 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001825 }
1826 cc_library {
1827 name: "afl_fuzz_static_lib",
1828 host_supported: true,
1829 srcs: ["static_file.c"],
1830 }
1831 cc_library {
1832 name: "libfuzzer_only_static_lib",
1833 host_supported: true,
1834 srcs: ["static_file.c"],
1835 }
1836 cc_library {
1837 name: "afl_fuzz_shared_lib",
1838 host_supported: true,
1839 srcs: ["shared_file.c"],
1840 static_libs: [
1841 "second_static_lib",
1842 ],
1843 }
1844 cc_library_headers {
1845 name: "libafl_headers",
1846 vendor_available: true,
1847 host_supported: true,
1848 export_include_dirs: [
1849 "include",
1850 "instrumentation",
1851 ],
1852 }
1853 cc_object {
1854 name: "afl-compiler-rt",
1855 vendor_available: true,
1856 host_supported: true,
1857 cflags: [
1858 "-fPIC",
1859 ],
1860 srcs: [
1861 "instrumentation/afl-compiler-rt.o.c",
1862 ],
1863 }
1864 cc_library {
1865 name: "second_static_lib",
1866 host_supported: true,
1867 srcs: ["second_file.c"],
1868 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001869 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001870 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001871 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001872 srcs: [
1873 "aflpp_driver.c",
1874 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001875 }`
1876
1877 testEnv := map[string]string{
1878 "FUZZ_FRAMEWORK": "AFL",
1879 }
1880
1881 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001882
1883 checkPcGuardFlag := func(
1884 modName string, variantName string, shouldHave bool) {
1885 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1886
1887 cFlags, ok := cc.Args["cFlags"]
1888 if !ok {
1889 t.Errorf("Could not find cFlags for module %s and variant %s",
1890 modName, variantName)
1891 }
1892
1893 if strings.Contains(
1894 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1895 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1896 "Test failed for module %s and variant %s",
1897 !shouldHave, shouldHave, modName, variantName)
1898 }
1899 }
1900
Cory Barkera1da26f2022-06-07 20:12:06 +00001901 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001902 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001903
1904 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001905 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001906 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001907
1908 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001909 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001910 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001911
1912 ctx.ModuleForTests("afl_fuzz_shared_lib",
1913 "android_arm64_armv8-a_shared").Rule("cc")
1914 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001915 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1916}
1917
1918func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001919 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001920 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1921}
1922
1923func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001924 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001925 if runtime.GOOS != "linux" {
1926 t.Skip("requires linux")
1927 }
1928
1929 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001930}
1931
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001932// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1933// correctly.
1934func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001935 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001936 ctx := testCc(t, `
1937 cc_fuzz {
1938 name: "fuzz_smoke_test",
1939 srcs: ["foo.c"],
1940 }`)
1941
Paul Duffin075c4172019-12-19 19:06:13 +00001942 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001943 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1944}
1945
Jooyung Han38002912019-05-16 04:01:54 +09001946func assertString(t *testing.T, got, expected string) {
1947 t.Helper()
1948 if got != expected {
1949 t.Errorf("expected %q got %q", expected, got)
1950 }
1951}
1952
1953func assertArrayString(t *testing.T, got, expected []string) {
1954 t.Helper()
1955 if len(got) != len(expected) {
1956 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1957 return
1958 }
1959 for i := range got {
1960 if got[i] != expected[i] {
1961 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1962 i, expected[i], expected, got[i], got)
1963 return
1964 }
1965 }
1966}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001967
Jooyung Han0302a842019-10-30 18:43:49 +09001968func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1969 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001970 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001971}
1972
Colin Crosse1bb5d02019-09-24 14:55:04 -07001973func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001974 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001975 ctx := testCc(t, `
1976 cc_defaults {
1977 name: "defaults",
1978 srcs: ["foo.c"],
1979 static: {
1980 srcs: ["bar.c"],
1981 },
1982 shared: {
1983 srcs: ["baz.c"],
1984 },
1985 }
1986
1987 cc_library_static {
1988 name: "libstatic",
1989 defaults: ["defaults"],
1990 }
1991
1992 cc_library_shared {
1993 name: "libshared",
1994 defaults: ["defaults"],
1995 }
1996
1997 cc_library {
1998 name: "libboth",
1999 defaults: ["defaults"],
2000 }
2001
2002 cc_binary {
2003 name: "binary",
2004 defaults: ["defaults"],
2005 }`)
2006
Colin Cross7113d202019-11-20 16:39:12 -08002007 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002008 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2009 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2010 }
Colin Cross7113d202019-11-20 16:39:12 -08002011 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002012 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2013 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2014 }
Colin Cross7113d202019-11-20 16:39:12 -08002015 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002016 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2017 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2018 }
2019
Colin Cross7113d202019-11-20 16:39:12 -08002020 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002021 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2022 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2023 }
Colin Cross7113d202019-11-20 16:39:12 -08002024 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002025 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2026 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2027 }
2028}
Colin Crosseabaedd2020-02-06 17:01:55 -08002029
2030func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002031 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08002032 bp := `
2033 cc_defaults {
2034 name: "libfoo_defaults",
2035 srcs: ["foo.c"],
2036 cppflags: ["-DFOO"],
2037 product_variables: {
2038 debuggable: {
2039 cppflags: ["-DBAR"],
2040 },
2041 },
2042 }
2043
2044 cc_library {
2045 name: "libfoo",
2046 defaults: ["libfoo_defaults"],
2047 }
2048 `
2049
Paul Duffin8567f222021-03-23 00:02:06 +00002050 result := android.GroupFixturePreparers(
2051 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002052 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08002053
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002054 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2055 variables.Debuggable = BoolPtr(true)
2056 }),
2057 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08002058
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002059 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00002060 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08002061}
Colin Crosse4f6eba2020-09-22 18:11:25 -07002062
2063func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
2064 t.Parallel()
2065 bp := `
2066 cc_library_static {
2067 name: "libfoo",
2068 srcs: ["foo.c"],
2069 whole_static_libs: ["libbar"],
2070 }
2071
2072 cc_library_static {
2073 name: "libbar",
2074 whole_static_libs: ["libmissing"],
2075 }
2076 `
2077
Paul Duffin8567f222021-03-23 00:02:06 +00002078 result := android.GroupFixturePreparers(
2079 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002080 android.PrepareForTestWithAllowMissingDependencies,
2081 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002082
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002083 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002084 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002085
Paul Duffine84b1332021-03-12 11:59:43 +00002086 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07002087
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002088 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002089 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07002090}
Colin Crosse9fe2942020-11-10 18:12:15 -08002091
2092func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002093 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08002094 bp := `
2095 cc_binary {
2096 name: "bin",
2097 host_supported: true,
2098 shared_libs: ["libshared"],
2099 runtime_libs: ["libruntime"],
2100 srcs: [":gen"],
2101 }
2102
2103 cc_library_shared {
2104 name: "libshared",
2105 host_supported: true,
2106 shared_libs: ["libtransitive"],
2107 }
2108
2109 cc_library_shared {
2110 name: "libtransitive",
2111 host_supported: true,
2112 }
2113
2114 cc_library_shared {
2115 name: "libruntime",
2116 host_supported: true,
2117 }
2118
2119 cc_binary_host {
2120 name: "tool",
2121 srcs: ["foo.cpp"],
2122 }
2123
2124 genrule {
2125 name: "gen",
2126 tools: ["tool"],
2127 out: ["gen.cpp"],
2128 cmd: "$(location tool) $(out)",
2129 }
2130 `
2131
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002132 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002133 ctx := testCcWithConfig(t, config)
2134
2135 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2136 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2137 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2138 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2139 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2140
2141 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2142 t.Errorf("expected host bin dependency %q, got %q", w, g)
2143 }
2144
2145 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2146 t.Errorf("expected host bin dependency %q, got %q", w, g)
2147 }
2148
2149 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2150 t.Errorf("expected host bin dependency %q, got %q", w, g)
2151 }
2152
2153 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2154 t.Errorf("expected host bin dependency %q, got %q", w, g)
2155 }
2156
2157 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2158 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2159 }
2160
2161 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2162 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2163 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2164 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2165
2166 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2167 t.Errorf("expected device bin dependency %q, got %q", w, g)
2168 }
2169
2170 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2171 t.Errorf("expected device bin dependency %q, got %q", w, g)
2172 }
2173
2174 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2175 t.Errorf("expected device bin dependency %q, got %q", w, g)
2176 }
2177
2178 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2179 t.Errorf("expected device bin dependency %q, got %q", w, g)
2180 }
2181
2182 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2183 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2184 }
2185
2186}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002187
2188func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002189 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002190 ctx := testCc(t, `
2191 cc_library_shared {
2192 name: "libclient",
2193 srcs: ["foo.c"],
2194 shared_libs: ["libfoo#1"],
2195 }
2196
2197 cc_library_shared {
2198 name: "libfoo",
2199 srcs: ["foo.c"],
2200 shared_libs: ["libbar"],
2201 export_shared_lib_headers: ["libbar"],
2202 stubs: {
2203 symbol_file: "foo.map.txt",
2204 versions: ["1", "2", "3"],
2205 },
2206 }
2207
2208 cc_library_shared {
2209 name: "libbar",
2210 export_include_dirs: ["include/libbar"],
2211 srcs: ["foo.c"],
2212 }`)
2213
2214 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2215
2216 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2217 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2218 }
2219}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002220
Vinh Tran09581952023-05-16 16:03:20 -04002221func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002222 t.Parallel()
2223 ctx := android.GroupFixturePreparers(
2224 prepareForCcTest,
2225 aidl_library.PrepareForTestWithAidlLibrary,
2226 android.MockFS{
2227 "package_bar/Android.bp": []byte(`
2228 aidl_library {
2229 name: "bar",
2230 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002231 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002232 strip_import_prefix: "x",
2233 }
2234 `)}.AddToFixture(),
2235 android.MockFS{
2236 "package_foo/Android.bp": []byte(`
2237 aidl_library {
2238 name: "foo",
2239 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002240 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002241 strip_import_prefix: "a",
2242 deps: ["bar"],
2243 }
2244 cc_library {
2245 name: "libfoo",
2246 aidl: {
2247 libs: ["foo"],
2248 }
2249 }
2250 `),
2251 }.AddToFixture(),
2252 ).RunTest(t).TestContext
2253
2254 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002255
2256 android.AssertPathsRelativeToTopEquals(
2257 t,
2258 "aidl headers",
2259 []string{
2260 "package_bar/x/HeaderBar.aidl",
2261 "package_foo/a/HeaderFoo.aidl",
2262 "package_foo/a/b/Foo.aidl",
2263 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2264 },
2265 libfoo.Rule("aidl_library").Implicits,
2266 )
2267
Colin Crossf61d03d2023-11-02 16:56:39 -07002268 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002269 aidlCommand := manifest.Commands[0].GetCommand()
2270
2271 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2272 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2273 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2274 }
2275
2276 outputs := strings.Join(libfoo.AllOutputs(), " ")
2277
Vinh Tran09581952023-05-16 16:03:20 -04002278 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2279 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2280 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002281 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2282 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002283 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2284 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2285 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002286 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2287}
2288
Jooyung Hane197d8b2021-01-05 10:33:16 +09002289func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002290 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002291 ctx := android.GroupFixturePreparers(
2292 prepareForCcTest,
2293 aidl_library.PrepareForTestWithAidlLibrary,
2294 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002295 cc_library {
2296 name: "libfoo",
2297 srcs: ["a/Foo.aidl"],
2298 aidl: { flags: ["-Werror"], },
2299 }
2300 `)
2301
2302 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002303 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002304 aidlCommand := manifest.Commands[0].GetCommand()
2305 expectedAidlFlag := "-Werror"
2306 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2307 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2308 }
2309}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002310
Jooyung Han07f70c02021-11-06 07:08:45 +09002311func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002312 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002313 for _, tc := range []struct {
2314 name string
2315 sdkVersion string
2316 variant string
2317 expected string
2318 }{
2319 {
2320 name: "default is current",
2321 sdkVersion: "",
2322 variant: "android_arm64_armv8-a_static",
2323 expected: "platform_apis",
2324 },
2325 {
2326 name: "use sdk_version",
2327 sdkVersion: `sdk_version: "29"`,
2328 variant: "android_arm64_armv8-a_static",
2329 expected: "platform_apis",
2330 },
2331 {
2332 name: "use sdk_version(sdk variant)",
2333 sdkVersion: `sdk_version: "29"`,
2334 variant: "android_arm64_armv8-a_sdk_static",
2335 expected: "29",
2336 },
2337 {
2338 name: "use min_sdk_version",
2339 sdkVersion: `min_sdk_version: "29"`,
2340 variant: "android_arm64_armv8-a_static",
2341 expected: "29",
2342 },
2343 } {
2344 t.Run(tc.name, func(t *testing.T) {
2345 ctx := testCc(t, `
2346 cc_library {
2347 name: "libfoo",
2348 stl: "none",
2349 srcs: ["a/Foo.aidl"],
2350 `+tc.sdkVersion+`
2351 }
2352 `)
2353 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002354 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002355 aidlCommand := manifest.Commands[0].GetCommand()
2356 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2357 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2358 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2359 }
2360 })
2361 }
2362}
2363
Vinh Tran09581952023-05-16 16:03:20 -04002364func TestInvalidAidlProp(t *testing.T) {
2365 t.Parallel()
2366
2367 testCases := []struct {
2368 description string
2369 bp string
2370 }{
2371 {
2372 description: "Invalid use of aidl.libs and aidl.include_dirs",
2373 bp: `
2374 cc_library {
2375 name: "foo",
2376 aidl: {
2377 libs: ["foo_aidl"],
2378 include_dirs: ["bar/include"],
2379 }
2380 }
2381 `,
2382 },
2383 {
2384 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2385 bp: `
2386 cc_library {
2387 name: "foo",
2388 aidl: {
2389 libs: ["foo_aidl"],
2390 local_include_dirs: ["include"],
2391 }
2392 }
2393 `,
2394 },
2395 }
2396
2397 for _, testCase := range testCases {
2398 t.Run(testCase.description, func(t *testing.T) {
2399 bp := `
2400 aidl_library {
2401 name: "foo_aidl",
2402 srcs: ["Foo.aidl"],
2403 } ` + testCase.bp
2404 android.GroupFixturePreparers(
2405 prepareForCcTest,
2406 aidl_library.PrepareForTestWithAidlLibrary.
2407 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2408 ).RunTestWithBp(t, bp)
2409 })
2410 }
2411}
2412
Jiyong Parka008fb02021-03-16 17:15:53 +09002413func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002414 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002415 ctx := testCc(t, `
2416 cc_library_shared {
2417 name: "libfoo",
2418 srcs: ["foo.c"],
2419 min_sdk_version: "29",
2420 }`)
2421
2422 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2423 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2424}
2425
Vinh Tranf1924742022-06-24 16:40:11 -04002426func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002427 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002428 bp := `
2429 cc_library_shared {
2430 name: "libfoo",
2431 srcs: ["foo.c"],
2432 min_sdk_version: "S",
2433 }
2434 `
2435 result := android.GroupFixturePreparers(
2436 prepareForCcTest,
2437 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2438 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2439 }),
2440 ).RunTestWithBp(t, bp)
2441 ctx := result.TestContext
2442 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2443 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2444}
2445
Paul Duffin3cb603e2021-02-19 13:57:10 +00002446func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002447 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002448
2449 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2450 // embedded newline characters alone.
2451 trimIndentingSpaces := func(s string) string {
2452 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2453 }
2454
2455 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2456 t.Helper()
2457 expected = trimIndentingSpaces(expected)
2458 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2459 if expected != actual {
2460 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2461 }
2462 }
2463
2464 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2465
2466 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2467 t.Helper()
Yu Liu663e4502024-08-12 18:23:59 +00002468 exported, _ := android.OtherModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002469 name := module.Name()
2470
2471 for _, checker := range checkers {
2472 checker(t, name, exported)
2473 }
2474 }
2475
2476 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2477 return func(t *testing.T, name string, exported FlagExporterInfo) {
2478 t.Helper()
2479 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2480 }
2481 }
2482
2483 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2484 return func(t *testing.T, name string, exported FlagExporterInfo) {
2485 t.Helper()
2486 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2487 }
2488 }
2489
2490 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2491 return func(t *testing.T, name string, exported FlagExporterInfo) {
2492 t.Helper()
2493 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2494 }
2495 }
2496
2497 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2498 return func(t *testing.T, name string, exported FlagExporterInfo) {
2499 t.Helper()
2500 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2501 }
2502 }
2503
2504 genRuleModules := `
2505 genrule {
2506 name: "genrule_foo",
2507 cmd: "generate-foo",
2508 out: [
2509 "generated_headers/foo/generated_header.h",
2510 ],
2511 export_include_dirs: [
2512 "generated_headers",
2513 ],
2514 }
2515
2516 genrule {
2517 name: "genrule_bar",
2518 cmd: "generate-bar",
2519 out: [
2520 "generated_headers/bar/generated_header.h",
2521 ],
2522 export_include_dirs: [
2523 "generated_headers",
2524 ],
2525 }
2526 `
2527
2528 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2529 ctx := testCc(t, genRuleModules+`
2530 cc_library {
2531 name: "libfoo",
2532 srcs: ["foo.c"],
2533 export_include_dirs: ["foo/standard"],
2534 export_system_include_dirs: ["foo/system"],
2535 generated_headers: ["genrule_foo"],
2536 export_generated_headers: ["genrule_foo"],
2537 }
2538
2539 cc_library {
2540 name: "libbar",
2541 srcs: ["bar.c"],
2542 shared_libs: ["libfoo"],
2543 export_include_dirs: ["bar/standard"],
2544 export_system_include_dirs: ["bar/system"],
2545 generated_headers: ["genrule_bar"],
2546 export_generated_headers: ["genrule_bar"],
2547 }
2548 `)
2549 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2550 checkIncludeDirs(t, ctx, foo,
2551 expectedIncludeDirs(`
2552 foo/standard
2553 .intermediates/genrule_foo/gen/generated_headers
2554 `),
2555 expectedSystemIncludeDirs(`foo/system`),
2556 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2557 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2558 )
2559
2560 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2561 checkIncludeDirs(t, ctx, bar,
2562 expectedIncludeDirs(`
2563 bar/standard
2564 .intermediates/genrule_bar/gen/generated_headers
2565 `),
2566 expectedSystemIncludeDirs(`bar/system`),
2567 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2568 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2569 )
2570 })
2571
2572 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2573 ctx := testCc(t, genRuleModules+`
2574 cc_library {
2575 name: "libfoo",
2576 srcs: ["foo.c"],
2577 export_include_dirs: ["foo/standard"],
2578 export_system_include_dirs: ["foo/system"],
2579 generated_headers: ["genrule_foo"],
2580 export_generated_headers: ["genrule_foo"],
2581 }
2582
2583 cc_library {
2584 name: "libbar",
2585 srcs: ["bar.c"],
2586 whole_static_libs: ["libfoo"],
2587 export_include_dirs: ["bar/standard"],
2588 export_system_include_dirs: ["bar/system"],
2589 generated_headers: ["genrule_bar"],
2590 export_generated_headers: ["genrule_bar"],
2591 }
2592 `)
2593 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2594 checkIncludeDirs(t, ctx, foo,
2595 expectedIncludeDirs(`
2596 foo/standard
2597 .intermediates/genrule_foo/gen/generated_headers
2598 `),
2599 expectedSystemIncludeDirs(`foo/system`),
2600 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2601 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2602 )
2603
2604 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2605 checkIncludeDirs(t, ctx, bar,
2606 expectedIncludeDirs(`
2607 bar/standard
2608 foo/standard
2609 .intermediates/genrule_foo/gen/generated_headers
2610 .intermediates/genrule_bar/gen/generated_headers
2611 `),
2612 expectedSystemIncludeDirs(`
2613 bar/system
2614 foo/system
2615 `),
2616 expectedGeneratedHeaders(`
2617 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2618 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2619 `),
2620 expectedOrderOnlyDeps(`
2621 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2622 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2623 `),
2624 )
2625 })
2626
Paul Duffin3cb603e2021-02-19 13:57:10 +00002627 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002628 ctx := android.GroupFixturePreparers(
2629 prepareForCcTest,
2630 aidl_library.PrepareForTestWithAidlLibrary,
2631 ).RunTestWithBp(t, `
2632 aidl_library {
2633 name: "libfoo_aidl",
2634 srcs: ["x/y/Bar.aidl"],
2635 strip_import_prefix: "x",
2636 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002637 cc_library_shared {
2638 name: "libfoo",
2639 srcs: [
2640 "foo.c",
2641 "b.aidl",
2642 "a.proto",
2643 ],
2644 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002645 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002646 export_aidl_headers: true,
2647 }
2648 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002649 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002650 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2651 checkIncludeDirs(t, ctx, foo,
2652 expectedIncludeDirs(`
2653 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002654 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002655 `),
2656 expectedSystemIncludeDirs(``),
2657 expectedGeneratedHeaders(`
2658 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2659 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2660 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002661 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2662 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2663 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002664 `),
2665 expectedOrderOnlyDeps(`
2666 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2667 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2668 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002669 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2670 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2671 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002672 `),
2673 )
2674 })
2675
Paul Duffin3cb603e2021-02-19 13:57:10 +00002676 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2677 ctx := testCc(t, genRuleModules+`
2678 cc_library_shared {
2679 name: "libfoo",
2680 srcs: [
2681 "foo.c",
2682 "b.aidl",
2683 "a.proto",
2684 ],
2685 proto: {
2686 export_proto_headers: true,
2687 }
2688 }
2689 `)
2690 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2691 checkIncludeDirs(t, ctx, foo,
2692 expectedIncludeDirs(`
2693 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2694 `),
2695 expectedSystemIncludeDirs(``),
2696 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002697 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2698 `),
2699 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002700 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2701 `),
2702 )
2703 })
2704
Paul Duffin33056e82021-02-19 13:49:08 +00002705 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002706 ctx := testCc(t, genRuleModules+`
2707 cc_library_shared {
2708 name: "libfoo",
2709 srcs: [
2710 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002711 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002712 "b.aidl",
2713 "a.proto",
2714 ],
2715 }
2716 `)
2717 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2718 checkIncludeDirs(t, ctx, foo,
2719 expectedIncludeDirs(`
2720 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2721 `),
2722 expectedSystemIncludeDirs(``),
2723 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002724 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002725 `),
2726 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002727 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2728 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002729 `),
2730 )
2731 })
2732}
Colin Crossae628182021-06-14 16:52:28 -07002733
2734func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002735 t.Parallel()
Liz Kammer08572c62021-09-30 10:11:04 -04002736 baseExpectedFlags := []string{
2737 "${config.ArmThumbCflags}",
2738 "${config.ArmCflags}",
2739 "${config.CommonGlobalCflags}",
2740 "${config.DeviceGlobalCflags}",
2741 "${config.ExternalCflags}",
2742 "${config.ArmToolchainCflags}",
2743 "${config.ArmArmv7ANeonCflags}",
2744 "${config.ArmGenericCflags}",
2745 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002746 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002747 }
2748
2749 expectedIncludes := []string{
2750 "external/foo/android_arm_export_include_dirs",
2751 "external/foo/lib32_export_include_dirs",
2752 "external/foo/arm_export_include_dirs",
2753 "external/foo/android_export_include_dirs",
2754 "external/foo/linux_export_include_dirs",
2755 "external/foo/export_include_dirs",
2756 "external/foo/android_arm_local_include_dirs",
2757 "external/foo/lib32_local_include_dirs",
2758 "external/foo/arm_local_include_dirs",
2759 "external/foo/android_local_include_dirs",
2760 "external/foo/linux_local_include_dirs",
2761 "external/foo/local_include_dirs",
2762 "external/foo",
2763 "external/foo/libheader1",
2764 "external/foo/libheader2",
2765 "external/foo/libwhole1",
2766 "external/foo/libwhole2",
2767 "external/foo/libstatic1",
2768 "external/foo/libstatic2",
2769 "external/foo/libshared1",
2770 "external/foo/libshared2",
2771 "external/foo/liblinux",
2772 "external/foo/libandroid",
2773 "external/foo/libarm",
2774 "external/foo/lib32",
2775 "external/foo/libandroid_arm",
Ryan Prichard2a69eb62024-07-30 01:58:54 +00002776 "defaults/cc/common/ndk_libc++_shared_include_dirs",
Liz Kammer08572c62021-09-30 10:11:04 -04002777 }
2778
2779 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2780 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2781
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002782 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002783 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002784 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002785
2786 lastIncludes := []string{
2787 "out/soong/ndk/sysroot/usr/include",
2788 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
2789 }
2790
2791 combineSlices := func(slices ...[]string) []string {
2792 var ret []string
2793 for _, s := range slices {
2794 ret = append(ret, s...)
2795 }
2796 return ret
2797 }
2798
2799 testCases := []struct {
2800 name string
2801 src string
2802 expected []string
2803 }{
2804 {
2805 name: "c",
2806 src: "foo.c",
Yi Kong13beeed2023-07-15 03:09:00 +09002807 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002808 },
2809 {
2810 name: "cc",
2811 src: "foo.cc",
Yi Kong13beeed2023-07-15 03:09:00 +09002812 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002813 },
2814 {
2815 name: "assemble",
2816 src: "foo.s",
Yi Kong13beeed2023-07-15 03:09:00 +09002817 expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
Liz Kammer08572c62021-09-30 10:11:04 -04002818 },
2819 }
2820
2821 for _, tc := range testCases {
2822 t.Run(tc.name, func(t *testing.T) {
2823 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002824 cc_library {
2825 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002826 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002827 cflags: ["-std=candcpp"],
2828 conlyflags: ["-std=conly"],
2829 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002830 local_include_dirs: ["local_include_dirs"],
2831 export_include_dirs: ["export_include_dirs"],
2832 export_system_include_dirs: ["export_system_include_dirs"],
2833 static_libs: ["libstatic1", "libstatic2"],
2834 whole_static_libs: ["libwhole1", "libwhole2"],
2835 shared_libs: ["libshared1", "libshared2"],
2836 header_libs: ["libheader1", "libheader2"],
2837 target: {
2838 android: {
2839 shared_libs: ["libandroid"],
2840 local_include_dirs: ["android_local_include_dirs"],
2841 export_include_dirs: ["android_export_include_dirs"],
2842 },
2843 android_arm: {
2844 shared_libs: ["libandroid_arm"],
2845 local_include_dirs: ["android_arm_local_include_dirs"],
2846 export_include_dirs: ["android_arm_export_include_dirs"],
2847 },
2848 linux: {
2849 shared_libs: ["liblinux"],
2850 local_include_dirs: ["linux_local_include_dirs"],
2851 export_include_dirs: ["linux_export_include_dirs"],
2852 },
2853 },
2854 multilib: {
2855 lib32: {
2856 shared_libs: ["lib32"],
2857 local_include_dirs: ["lib32_local_include_dirs"],
2858 export_include_dirs: ["lib32_export_include_dirs"],
2859 },
2860 },
2861 arch: {
2862 arm: {
2863 shared_libs: ["libarm"],
2864 local_include_dirs: ["arm_local_include_dirs"],
2865 export_include_dirs: ["arm_export_include_dirs"],
2866 },
2867 },
2868 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002869 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002870 }
2871
2872 cc_library_headers {
2873 name: "libheader1",
2874 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002875 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002876 stl: "none",
2877 }
2878
2879 cc_library_headers {
2880 name: "libheader2",
2881 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002882 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002883 stl: "none",
2884 }
Liz Kammer08572c62021-09-30 10:11:04 -04002885 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002886
Liz Kammer08572c62021-09-30 10:11:04 -04002887 libs := []string{
2888 "libstatic1",
2889 "libstatic2",
2890 "libwhole1",
2891 "libwhole2",
2892 "libshared1",
2893 "libshared2",
2894 "libandroid",
2895 "libandroid_arm",
2896 "liblinux",
2897 "lib32",
2898 "libarm",
2899 }
Colin Crossae628182021-06-14 16:52:28 -07002900
Liz Kammer08572c62021-09-30 10:11:04 -04002901 for _, lib := range libs {
2902 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002903 cc_library {
2904 name: "%s",
2905 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002906 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002907 stl: "none",
2908 }
2909 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002910 }
2911
2912 ctx := android.GroupFixturePreparers(
2913 PrepareForIntegrationTestWithCc,
2914 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2915 ).RunTest(t)
Liz Kammer08572c62021-09-30 10:11:04 -04002916 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
2917
2918 var includes []string
2919 flags := strings.Split(cflags, " ")
2920 for _, flag := range flags {
2921 if strings.HasPrefix(flag, "-I") {
2922 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2923 } else if flag == "-isystem" {
2924 // skip isystem, include next
2925 } else if len(flag) > 0 {
2926 includes = append(includes, flag)
2927 }
2928 }
2929
2930 android.AssertArrayString(t, "includes", tc.expected, includes)
2931 })
Colin Crossae628182021-06-14 16:52:28 -07002932 }
2933
Colin Crossae628182021-06-14 16:52:28 -07002934}
Alixb5f6d9e2022-04-20 23:00:58 +00002935
zijunzhao933e3802023-01-12 07:26:20 +00002936func TestAddnoOverride64GlobalCflags(t *testing.T) {
2937 t.Parallel()
2938 ctx := testCc(t, `
2939 cc_library_shared {
2940 name: "libclient",
2941 srcs: ["foo.c"],
2942 shared_libs: ["libfoo#1"],
2943 }
2944
2945 cc_library_shared {
2946 name: "libfoo",
2947 srcs: ["foo.c"],
2948 shared_libs: ["libbar"],
2949 export_shared_lib_headers: ["libbar"],
2950 stubs: {
2951 symbol_file: "foo.map.txt",
2952 versions: ["1", "2", "3"],
2953 },
2954 }
2955
2956 cc_library_shared {
2957 name: "libbar",
2958 export_include_dirs: ["include/libbar"],
2959 srcs: ["foo.c"],
2960 }`)
2961
2962 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2963
2964 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2965 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2966 }
2967}
2968
Alixb5f6d9e2022-04-20 23:00:58 +00002969func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002970 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002971 tests := []struct {
2972 name string
2973 clang bool
2974 BuildBrokenClangProperty bool
2975 err string
2976 }{
2977 {
2978 name: "error when clang is set to false",
2979 clang: false,
2980 err: "is no longer supported",
2981 },
2982 {
2983 name: "error when clang is set to true",
2984 clang: true,
2985 err: "property is deprecated, see Changes.md",
2986 },
2987 {
2988 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2989 clang: true,
2990 BuildBrokenClangProperty: true,
2991 },
2992 }
2993
2994 for _, test := range tests {
2995 t.Run(test.name, func(t *testing.T) {
2996 bp := fmt.Sprintf(`
2997 cc_library {
2998 name: "foo",
2999 clang: %t,
3000 }`, test.clang)
3001
3002 if test.err == "" {
3003 android.GroupFixturePreparers(
3004 prepareForCcTest,
3005 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3006 if test.BuildBrokenClangProperty {
3007 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
3008 }
3009 }),
3010 ).RunTestWithBp(t, bp)
3011 } else {
3012 prepareForCcTest.
3013 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3014 RunTestWithBp(t, bp)
3015 }
3016 })
3017 }
3018}
Alix Espinoef47e542022-09-14 19:10:51 +00003019
3020func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003021 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003022 tests := []struct {
3023 name string
3024 clangAsFlags []string
3025 BuildBrokenClangAsFlags bool
3026 err string
3027 }{
3028 {
3029 name: "error when clang_asflags is set",
3030 clangAsFlags: []string{"-a", "-b"},
3031 err: "clang_asflags: property is deprecated",
3032 },
3033 {
3034 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3035 clangAsFlags: []string{"-a", "-b"},
3036 BuildBrokenClangAsFlags: true,
3037 },
3038 }
3039
3040 for _, test := range tests {
3041 t.Run(test.name, func(t *testing.T) {
3042 bp := fmt.Sprintf(`
3043 cc_library {
3044 name: "foo",
3045 clang_asflags: %s,
3046 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3047
3048 if test.err == "" {
3049 android.GroupFixturePreparers(
3050 prepareForCcTest,
3051 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3052 if test.BuildBrokenClangAsFlags {
3053 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3054 }
3055 }),
3056 ).RunTestWithBp(t, bp)
3057 } else {
3058 prepareForCcTest.
3059 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3060 RunTestWithBp(t, bp)
3061 }
3062 })
3063 }
3064}
3065
3066func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003067 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003068 tests := []struct {
3069 name string
3070 clangCFlags []string
3071 BuildBrokenClangCFlags bool
3072 err string
3073 }{
3074 {
3075 name: "error when clang_cflags is set",
3076 clangCFlags: []string{"-a", "-b"},
3077 err: "clang_cflags: property is deprecated",
3078 },
3079 {
3080 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3081 clangCFlags: []string{"-a", "-b"},
3082 BuildBrokenClangCFlags: true,
3083 },
3084 }
3085
3086 for _, test := range tests {
3087 t.Run(test.name, func(t *testing.T) {
3088 bp := fmt.Sprintf(`
3089 cc_library {
3090 name: "foo",
3091 clang_cflags: %s,
3092 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3093
3094 if test.err == "" {
3095 android.GroupFixturePreparers(
3096 prepareForCcTest,
3097 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3098 if test.BuildBrokenClangCFlags {
3099 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3100 }
3101 }),
3102 ).RunTestWithBp(t, bp)
3103 } else {
3104 prepareForCcTest.
3105 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3106 RunTestWithBp(t, bp)
3107 }
3108 })
3109 }
3110}
Wei Li5f5d2712023-12-11 15:40:29 -08003111
3112func TestStrippedAllOutputFile(t *testing.T) {
3113 t.Parallel()
3114 bp := `
3115 cc_library {
3116 name: "test_lib",
3117 srcs: ["test_lib.cpp"],
3118 dist: {
3119 targets: [ "dist_target" ],
3120 tag: "stripped_all",
3121 }
3122 }
3123 `
3124 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3125 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07003126 testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
Yu Liu51c22312024-08-20 23:56:15 +00003127 outputFile := testingModule.OutputFiles(ctx, t, "stripped_all")
Wei Li5f5d2712023-12-11 15:40:29 -08003128 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3129 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3130 return
3131 }
3132}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003133
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003134func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003135 t.Parallel()
3136
3137 bp := `
3138 cc_binary {
3139 name: "binfoo",
3140 srcs: ["binfoo.cc"],
3141 vendor_available: true,
3142 product_available: true,
3143 shared_libs: ["libbar"]
3144 }
3145 cc_library {
3146 name: "libbar",
3147 srcs: ["libbar.cc"],
3148 vendor_available: true,
3149 product_available: true,
3150 }
3151 `
3152
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003153 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003154
3155 hasDep := func(m android.Module, wantDep android.Module) bool {
3156 t.Helper()
3157 var found bool
3158 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3159 if dep == wantDep {
3160 found = true
3161 }
3162 })
3163 return found
3164 }
3165
3166 testDepWithVariant := func(imageVariant string) {
3167 imageVariantStr := ""
3168 if imageVariant != "core" {
3169 imageVariantStr = "_" + imageVariant
3170 }
3171 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3172 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3173 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3174 }
3175
3176 testDepWithVariant("core")
3177 testDepWithVariant("vendor")
3178 testDepWithVariant("product")
3179}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003180
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003181func TestVendorSdkVersion(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003182 t.Parallel()
3183
3184 bp := `
3185 cc_library {
3186 name: "libfoo",
3187 srcs: ["libfoo.cc"],
3188 vendor_available: true,
3189 }
3190
3191 cc_library {
3192 name: "libbar",
3193 srcs: ["libbar.cc"],
3194 vendor_available: true,
3195 min_sdk_version: "29",
3196 }
3197 `
3198
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003199 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003200 testSdkVersionFlag := func(module, version string) {
3201 flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3202 android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
3203 }
3204
3205 testSdkVersionFlag("libfoo", "10000")
3206 testSdkVersionFlag("libbar", "29")
3207
3208 ctx = android.GroupFixturePreparers(
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003209 prepareForCcTest,
Colin Crossa66b4632024-08-08 15:50:47 -07003210 android.PrepareForTestWithBuildFlag("RELEASE_BOARD_API_LEVEL_FROZEN", "true"),
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003211 ).RunTestWithBp(t, bp)
3212 testSdkVersionFlag("libfoo", "30")
3213 testSdkVersionFlag("libbar", "29")
3214}
kellyhungd62ea302024-05-19 21:16:07 +08003215
3216func TestClangVerify(t *testing.T) {
3217 t.Parallel()
3218
3219 ctx := testCc(t, `
3220 cc_library {
3221 name: "lib_no_clang_verify",
3222 srcs: ["libnocv.cc"],
3223 }
3224
3225 cc_library {
3226 name: "lib_clang_verify",
3227 srcs: ["libcv.cc"],
3228 clang_verify: true,
3229 }
3230 `)
3231
3232 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
3233
3234 cFlags_no_cv := module.Rule("cc").Args["cFlags"]
3235 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
3236 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
3237 }
3238
3239 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3240 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
3241 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
3242 }
3243}