blob: 144b90b94daabca6fca1ccffc46fd84a5906f888 [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"
Colin Crossdd81e672024-10-17 14:01:12 -070023 "slices"
Jeff Gaston294356f2017-09-27 17:05:30 -070024 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070025 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070026
Vinh Tran367d89d2023-04-28 11:21:25 -040027 "android/soong/aidl_library"
Colin Crosse1bb5d02019-09-24 14:55:04 -070028 "android/soong/android"
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090029
30 "github.com/google/blueprint"
Colin Cross74d1ec02015-04-28 13:30:13 -070031)
32
Yu Liue4312402023-01-18 09:15:31 -080033func init() {
34 registerTestMutators(android.InitRegistrationContext)
35}
36
Jiyong Park6a43f042017-10-12 23:05:00 +090037func TestMain(m *testing.M) {
Paul Duffinc3e6ce02021-03-22 23:21:32 +000038 os.Exit(m.Run())
Jiyong Park6a43f042017-10-12 23:05:00 +090039}
40
Paul Duffin2e6f90e2021-03-22 23:20:25 +000041var prepareForCcTest = android.GroupFixturePreparers(
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090042 PrepareForIntegrationTestWithCc,
43 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
44 variables.VendorApiLevel = StringPtr("202404")
45 }),
46)
47
Yu Liue4312402023-01-18 09:15:31 -080048var apexVariationName = "apex28"
49var apexVersion = "28"
50
51func registerTestMutators(ctx android.RegistrationContext) {
52 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -070053 ctx.Transition("apex", &testApexTransitionMutator{})
Yu Liue4312402023-01-18 09:15:31 -080054 })
55}
56
Colin Crossd27205e2024-09-12 22:41:37 -070057type testApexTransitionMutator struct{}
58
59func (t *testApexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
60 return []string{apexVariationName}
61}
62
63func (t *testApexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
64 return sourceVariation
65}
66
67func (t *testApexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
68 return incomingVariation
69}
70
71func (t *testApexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
Yu Liue4312402023-01-18 09:15:31 -080072 apexInfo := android.ApexInfo{
73 ApexVariationName: apexVariationName,
74 MinSdkVersion: android.ApiLevelForTest(apexVersion),
75 }
Colin Crossd27205e2024-09-12 22:41:37 -070076 android.SetProvider(ctx, android.ApexInfoProvider, apexInfo)
Yu Liue4312402023-01-18 09:15:31 -080077}
78
Paul Duffin8567f222021-03-23 00:02:06 +000079// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000080//
81// See testCc for an explanation as to how to stop using this deprecated method.
82//
83// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080084func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070085 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000086 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000087 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090088}
89
Paul Duffin8567f222021-03-23 00:02:06 +000090// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000091//
Paul Duffin8567f222021-03-23 00:02:06 +000092// 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 +000093// easier to customize the test behavior.
94//
95// 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 +000096// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000097// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
98// that it did not change the test behavior unexpectedly.
99//
100// deprecated
Logan Chienf3511742017-10-31 18:04:35 +0800101func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800102 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +0000103 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +0000104 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +0800105}
106
Paul Duffin8567f222021-03-23 00:02:06 +0000107// testCcErrorWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000108//
109// See testCc for an explanation as to how to stop using this deprecated method.
110//
111// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900112func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800113 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800114
Paul Duffin8567f222021-03-23 00:02:06 +0000115 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000116 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
117 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800118}
119
Paul Duffin8567f222021-03-23 00:02:06 +0000120// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000121//
122// See testCc for an explanation as to how to stop using this deprecated method.
123//
124// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900125func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900126 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000127 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900128 testCcErrorWithConfig(t, pattern, config)
129 return
130}
131
Logan Chienf3511742017-10-31 18:04:35 +0800132const (
Colin Cross7113d202019-11-20 16:39:12 -0800133 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900134 vendorVariant = "android_vendor_arm64_armv8-a_shared"
135 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800136 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800137)
138
Paul Duffindb462dd2021-03-21 22:01:55 +0000139// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
140// running it in a fixture that requires all source files to exist.
141func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
142 android.GroupFixturePreparers(
143 PrepareForTestWithCcDefaultModules,
144 android.PrepareForTestDisallowNonExistentPaths,
145 ).RunTest(t)
146}
147
Jiyong Park6a43f042017-10-12 23:05:00 +0900148func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400149 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900150 ctx := testCc(t, `
151 cc_library {
152 name: "libTest",
153 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700154 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800155 nocrt: true,
156 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900157 vendor_available: true,
158 target: {
159 vendor: {
160 srcs: ["bar.c"],
161 },
162 },
163 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900164 `)
165
Logan Chienf3511742017-10-31 18:04:35 +0800166 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900167 var objs []string
168 for _, o := range ld.Inputs {
169 objs = append(objs, o.Base())
170 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800171 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900172 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
173 }
174}
175
Justin Yun7f99ec72021-04-12 13:19:28 +0900176func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
177 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
178 partitionDefined := false
179 checkPartition := func(specific bool, partition string) {
180 if specific {
181 if expected != partition && !partitionDefined {
182 // The variant is installed to the 'partition'
183 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
184 }
185 partitionDefined = true
186 } else {
187 // The variant is not installed to the 'partition'
188 if expected == partition {
189 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
190 }
191 }
192 }
193 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800194 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900195 }
196 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800197 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900198 }
199 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800200 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900201 }
202 systemExtSpecific := func(m *Module) bool {
203 return m.SystemExtSpecific()
204 }
205 checkPartition(socSpecific(mod), "vendor")
206 checkPartition(deviceSpecific(mod), "odm")
207 checkPartition(productSpecific(mod), "product")
208 checkPartition(systemExtSpecific(mod), "system_ext")
209 if !partitionDefined && expected != "system" {
210 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
211 " but installed to system partition", variant, name, expected)
212 }
213}
214
215func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400216 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900217 t.Helper()
218 ctx := prepareForCcTest.RunTestWithBp(t, `
219 cc_library {
220 name: "libsystem",
221 }
222 cc_library {
223 name: "libsystem_ext",
224 system_ext_specific: true,
225 }
226 cc_library {
227 name: "libproduct",
228 product_specific: true,
229 }
230 cc_library {
231 name: "libvendor",
232 vendor: true,
233 }
234 cc_library {
235 name: "libodm",
236 device_specific: true,
237 }
238 cc_library {
239 name: "liball_available",
240 vendor_available: true,
241 product_available: true,
242 }
243 cc_library {
244 name: "libsystem_ext_all_available",
245 system_ext_specific: true,
246 vendor_available: true,
247 product_available: true,
248 }
249 cc_library {
250 name: "liball_available_odm",
251 odm_available: true,
252 product_available: true,
253 }
254 cc_library {
255 name: "libproduct_vendoravailable",
256 product_specific: true,
257 vendor_available: true,
258 }
259 cc_library {
260 name: "libproduct_odmavailable",
261 product_specific: true,
262 odm_available: true,
263 }
264 `).TestContext
265
266 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
267 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
268 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
269 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
270 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
271
272 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
273 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
274 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
275
276 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
277 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
278 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
279
280 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
281 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
282 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
283
284 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
285 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
286
287 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
288 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
289}
290
Colin Crossf61d03d2023-11-02 16:56:39 -0700291func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900292 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700293 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800294 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900295 assertArrayString(t, actual, expected)
296}
297
Chris Parsons79d66a52020-06-05 17:26:16 -0400298func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400299 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400300 bp := `
301 cc_test_library {
302 name: "test_lib",
303 srcs: ["test_lib.cpp"],
304 gtest: false,
305 }
306
307 cc_test {
308 name: "main_test",
309 data_libs: ["test_lib"],
310 gtest: false,
311 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400312 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400313
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000314 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400315
316 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700317 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
318 testBinary := testingModule.Module().(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000319 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons79d66a52020-06-05 17:26:16 -0400320 if len(outputFiles) != 1 {
321 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
322 return
323 }
324 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800325 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400326 return
327 }
328
329 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400330 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400331
332 if !strings.HasSuffix(outputPath, "/main_test") {
333 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
334 return
335 }
336 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
337 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
338 return
339 }
340}
341
Chris Parsons216e10a2020-07-09 17:12:52 -0400342func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400343 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400344 bp := `
345 cc_test_library {
346 name: "test_lib",
347 srcs: ["test_lib.cpp"],
348 relative_install_path: "foo/bar/baz",
349 gtest: false,
350 }
351
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400352 cc_binary {
353 name: "test_bin",
354 relative_install_path: "foo/bar/baz",
355 compile_multilib: "both",
356 }
357
Chris Parsons216e10a2020-07-09 17:12:52 -0400358 cc_test {
359 name: "main_test",
360 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400361 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400362 gtest: false,
363 }
364 `
365
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000366 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400367
368 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700369 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
370 module := testingModule.Module()
Chris Parsons216e10a2020-07-09 17:12:52 -0400371 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000372 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons216e10a2020-07-09 17:12:52 -0400373 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400374 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400375 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400376 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800377 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400378 }
379
380 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400381
382 if !strings.HasSuffix(outputPath, "/main_test") {
383 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
384 }
Yu Liue70976d2024-10-15 20:45:35 +0000385 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Chris Parsons216e10a2020-07-09 17:12:52 -0400386 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
387 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400388 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400389 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400390 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
391 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
392 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
393 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400394}
395
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000396func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400397 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000398 bp := `
399 cc_test {
400 name: "main_test",
401 srcs: ["main_test.cpp"],
402 test_suites: [
403 "suite_1",
404 "suite_2",
405 ],
406 gtest: false,
407 }
408 `
409
410 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
411 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
412
Yu Liue70976d2024-10-15 20:45:35 +0000413 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000414 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
415 if len(compatEntries) != 2 {
416 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
417 }
418 if compatEntries[0] != "suite_1" {
419 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
420 " but was '%s'", compatEntries[0])
421 }
422 if compatEntries[1] != "suite_2" {
423 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
424 " but was '%s'", compatEntries[1])
425 }
426}
427
428func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400429 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000430 bp := `
431 cc_test_library {
432 name: "main_test_lib",
433 srcs: ["main_test_lib.cpp"],
434 test_suites: [
435 "suite_1",
436 "suite_2",
437 ],
438 gtest: false,
439 }
440 `
441
442 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
443 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
444
Yu Liue70976d2024-10-15 20:45:35 +0000445 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000446 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
447 if len(compatEntries) != 2 {
448 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
449 }
450 if compatEntries[0] != "suite_1" {
451 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
452 " but was '%s'", compatEntries[0])
453 }
454 if compatEntries[1] != "suite_2" {
455 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
456 " but was '%s'", compatEntries[1])
457 }
458}
459
Jooyung Hana70f0672019-01-18 15:20:43 +0900460func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400461 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900462 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900463 testCc(t, `
464 cc_library {
465 name: "libllndk",
466 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700467 llndk: {
468 symbol_file: "libllndk.map.txt",
469 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900470 }
471
472 cc_library {
473 name: "libdoubleloadable",
474 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900475 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900476 double_loadable: true,
477 }
478 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900479 // okay to link : double_loadable -> double_loadable
480 testCc(t, `
481 cc_library {
482 name: "libdoubleloadable1",
483 shared_libs: ["libdoubleloadable2"],
484 vendor_available: true,
485 double_loadable: true,
486 }
487
488 cc_library {
489 name: "libdoubleloadable2",
490 vendor_available: true,
491 double_loadable: true,
492 }
493 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900494 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900495 testCc(t, `
496 cc_library {
497 name: "libdoubleloadable",
498 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900499 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900500 double_loadable: true,
501 shared_libs: ["libnondoubleloadable"],
502 }
503
504 cc_library {
505 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900506 vendor_available: true,
507 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900508 double_loadable: true,
509 }
510 `)
511 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
512 testCc(t, `
513 cc_library {
514 name: "libllndk",
515 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700516 llndk: {
517 symbol_file: "libllndk.map.txt",
518 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900519 }
520
521 cc_library {
522 name: "libcoreonly",
523 shared_libs: ["libvendoravailable"],
524 }
525
526 // indirect dependency of LLNDK
527 cc_library {
528 name: "libvendoravailable",
529 vendor_available: true,
530 double_loadable: true,
531 }
532 `)
533}
534
535func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400536 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900537 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900538 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
539 cc_library {
540 name: "libllndk",
541 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700542 llndk: {
543 symbol_file: "libllndk.map.txt",
544 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900545 }
546
547 cc_library {
548 name: "libnondoubleloadable",
549 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900550 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900551 }
552 `)
553
554 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
555 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
556 cc_library {
557 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700558 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900559 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700560 llndk: {
561 symbol_file: "libllndk.map.txt",
562 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900563 }
564
565 cc_library {
566 name: "libnondoubleloadable",
567 vendor_available: true,
568 }
569 `)
570
Jooyung Hana70f0672019-01-18 15:20:43 +0900571 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
572 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
573 cc_library {
574 name: "libllndk",
575 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700576 llndk: {
577 symbol_file: "libllndk.map.txt",
578 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900579 }
580
581 cc_library {
582 name: "libcoreonly",
583 shared_libs: ["libvendoravailable"],
584 }
585
586 // indirect dependency of LLNDK
587 cc_library {
588 name: "libvendoravailable",
589 vendor_available: true,
590 }
591 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900592
593 // The error is not from 'client' but from 'libllndk'
594 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
595 cc_library {
596 name: "client",
597 vendor_available: true,
598 double_loadable: true,
599 shared_libs: ["libllndk"],
600 }
601 cc_library {
602 name: "libllndk",
603 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700604 llndk: {
605 symbol_file: "libllndk.map.txt",
606 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900607 }
608 cc_library {
609 name: "libnondoubleloadable",
610 vendor_available: true,
611 }
612 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800613}
614
Jooyung Han38002912019-05-16 04:01:54 +0900615func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400616 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800617 bp := `
618 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800619 name: "libvendor",
620 vendor: true,
621 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800622 vndk_prebuilt_shared {
623 name: "prevndk",
624 version: "27",
625 target_arch: "arm",
626 binder32bit: true,
627 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900628 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800629 vndk: {
630 enabled: true,
631 },
632 arch: {
633 arm: {
634 srcs: ["liba.so"],
635 },
636 },
637 }
638 cc_library {
639 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700640 llndk: {
641 symbol_file: "libllndk.map.txt",
642 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800643 }
644 cc_library {
645 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700646 llndk: {
647 symbol_file: "libllndkprivate.map.txt",
648 private: true,
649 }
Colin Cross78212242021-01-06 14:51:30 -0800650 }
Colin Cross78212242021-01-06 14:51:30 -0800651 llndk_libraries_txt {
652 name: "llndk.libraries.txt",
653 }
Colin Cross78212242021-01-06 14:51:30 -0800654 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800655
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000656 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900657 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800658 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900659
Colin Crossfb0c16e2019-11-20 17:12:35 -0800660 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900661
Jooyung Han38002912019-05-16 04:01:54 +0900662 tests := []struct {
663 variant string
664 name string
665 expected string
666 }{
Jooyung Han38002912019-05-16 04:01:54 +0900667 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800668 {vendorVariant, "libllndk", "native:vndk"},
Kiyoung Kim9f26fcf2024-05-27 17:25:52 +0900669 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +0900670 {coreVariant, "libllndk", "native:platform"},
671 }
672 for _, test := range tests {
673 t.Run(test.name, func(t *testing.T) {
674 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
675 assertString(t, module.makeLinkType, test.expected)
676 })
677 }
678}
679
Jeff Gaston294356f2017-09-27 17:05:30 -0700680var staticLinkDepOrderTestCases = []struct {
681 // This is a string representation of a map[moduleName][]moduleDependency .
682 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800683 inStatic string
684
685 // This is a string representation of a map[moduleName][]moduleDependency .
686 // It models the dependencies declared in an Android.bp file.
687 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700688
689 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
690 // The keys of allOrdered specify which modules we would like to check.
691 // The values of allOrdered specify the expected result (of the transitive closure of all
692 // dependencies) for each module to test
693 allOrdered string
694
695 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
696 // The keys of outOrdered specify which modules we would like to check.
697 // The values of outOrdered specify the expected result (of the ordered linker command line)
698 // for each module to test.
699 outOrdered string
700}{
701 // Simple tests
702 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800703 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700704 outOrdered: "",
705 },
706 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800707 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700708 outOrdered: "a:",
709 },
710 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800711 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700712 outOrdered: "a:b; b:",
713 },
714 // Tests of reordering
715 {
716 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800717 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700718 outOrdered: "a:b,c,d; b:d; c:d; d:",
719 },
720 {
721 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800722 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700723 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
724 },
725 {
726 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800727 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700728 outOrdered: "a:d,b,e,c; d:b; e:c",
729 },
730 {
731 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800732 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700733 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
734 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
735 },
736 {
737 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800738 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 -0700739 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
740 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
741 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800742 // shared dependencies
743 {
744 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
745 // So, we don't actually have to check that a shared dependency of c will change the order
746 // of a library that depends statically on b and on c. We only need to check that if c has
747 // a shared dependency on b, that that shows up in allOrdered.
748 inShared: "c:b",
749 allOrdered: "c:b",
750 outOrdered: "c:",
751 },
752 {
753 // This test doesn't actually include any shared dependencies but it's a reminder of what
754 // the second phase of the above test would look like
755 inStatic: "a:b,c; c:b",
756 allOrdered: "a:c,b; c:b",
757 outOrdered: "a:c,b; c:b",
758 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700759 // tiebreakers for when two modules specifying different orderings and there is no dependency
760 // to dictate an order
761 {
762 // 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 -0800763 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700764 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
765 },
766 {
767 // 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 -0800768 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 -0700769 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
770 },
771 // Tests involving duplicate dependencies
772 {
773 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800774 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700775 outOrdered: "a:c,b",
776 },
777 {
778 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800779 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700780 outOrdered: "a:d,c,b",
781 },
782 // Tests to confirm the nonexistence of infinite loops.
783 // These cases should never happen, so as long as the test terminates and the
784 // result is deterministic then that should be fine.
785 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800786 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700787 outOrdered: "a:a",
788 },
789 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800790 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700791 allOrdered: "a:b,c; b:c,a; c:a,b",
792 outOrdered: "a:b; b:c; c:a",
793 },
794 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800795 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700796 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
797 outOrdered: "a:c,b; b:a,c; c:b,a",
798 },
799}
800
801// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
802func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
803 // convert from "a:b,c; d:e" to "a:b,c;d:e"
804 strippedText := strings.Replace(text, " ", "", -1)
805 if len(strippedText) < 1 {
806 return []android.Path{}, make(map[android.Path][]android.Path, 0)
807 }
808 allDeps = make(map[android.Path][]android.Path, 0)
809
810 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
811 moduleTexts := strings.Split(strippedText, ";")
812
813 outputForModuleName := func(moduleName string) android.Path {
814 return android.PathForTesting(moduleName)
815 }
816
817 for _, moduleText := range moduleTexts {
818 // convert from "a:b,c" to ["a", "b,c"]
819 components := strings.Split(moduleText, ":")
820 if len(components) != 2 {
821 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
822 }
823 moduleName := components[0]
824 moduleOutput := outputForModuleName(moduleName)
825 modulesInOrder = append(modulesInOrder, moduleOutput)
826
827 depString := components[1]
828 // convert from "b,c" to ["b", "c"]
829 depNames := strings.Split(depString, ",")
830 if len(depString) < 1 {
831 depNames = []string{}
832 }
833 var deps []android.Path
834 for _, depName := range depNames {
835 deps = append(deps, outputForModuleName(depName))
836 }
837 allDeps[moduleOutput] = deps
838 }
839 return modulesInOrder, allDeps
840}
841
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800842func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400843 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700844 ctx := testCc(t, `
845 cc_library {
846 name: "a",
847 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900848 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700849 }
850 cc_library {
851 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900852 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700853 }
854 cc_library {
855 name: "c",
856 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900857 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700858 }
859 cc_library {
860 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900861 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700862 }
863
864 `)
865
Colin Cross7113d202019-11-20 16:39:12 -0800866 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700867 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000868 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800869 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400870 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700871
872 if !reflect.DeepEqual(actual, expected) {
873 t.Errorf("staticDeps orderings were not propagated correctly"+
874 "\nactual: %v"+
875 "\nexpected: %v",
876 actual,
877 expected,
878 )
879 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900880}
Jeff Gaston294356f2017-09-27 17:05:30 -0700881
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800882func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400883 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800884 ctx := testCc(t, `
885 cc_library {
886 name: "a",
887 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900888 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800889 }
890 cc_library {
891 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900892 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800893 }
894 cc_library {
895 name: "c",
896 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900897 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800898 }
899
900 `)
901
Colin Cross7113d202019-11-20 16:39:12 -0800902 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800903 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000904 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800905 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400906 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800907
908 if !reflect.DeepEqual(actual, expected) {
909 t.Errorf("staticDeps orderings did not account for shared libs"+
910 "\nactual: %v"+
911 "\nexpected: %v",
912 actual,
913 expected,
914 )
915 }
916}
917
Jooyung Hanb04a4992020-03-13 18:57:35 +0900918func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700919 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900920 if !reflect.DeepEqual(actual, expected) {
921 t.Errorf(message+
922 "\nactual: %v"+
923 "\nexpected: %v",
924 actual,
925 expected,
926 )
927 }
928}
929
Jooyung Han61b66e92020-03-21 14:21:46 +0000930func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400931 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800932 result := prepareForCcTest.RunTestWithBp(t, `
933 cc_library {
934 name: "libllndk",
935 stubs: { versions: ["1", "2"] },
936 llndk: {
937 symbol_file: "libllndk.map.txt",
938 },
939 export_include_dirs: ["include"],
940 }
941
942 cc_prebuilt_library_shared {
943 name: "libllndkprebuilt",
Spandan Das357ffcc2024-07-24 18:07:48 +0000944 stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" },
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800945 llndk: {
946 symbol_file: "libllndkprebuilt.map.txt",
947 },
948 }
949
950 cc_library {
951 name: "libllndk_with_external_headers",
952 stubs: { versions: ["1", "2"] },
953 llndk: {
954 symbol_file: "libllndk.map.txt",
955 export_llndk_headers: ["libexternal_llndk_headers"],
956 },
957 header_libs: ["libexternal_headers"],
958 export_header_lib_headers: ["libexternal_headers"],
959 }
960 cc_library_headers {
961 name: "libexternal_headers",
962 export_include_dirs: ["include"],
963 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900964 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800965 }
966 cc_library_headers {
967 name: "libexternal_llndk_headers",
968 export_include_dirs: ["include_llndk"],
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800969 export_system_include_dirs: ["include_system_llndk"],
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800970 llndk: {
971 symbol_file: "libllndk.map.txt",
972 },
973 vendor_available: true,
974 }
975
976 cc_library {
977 name: "libllndk_with_override_headers",
978 stubs: { versions: ["1", "2"] },
979 llndk: {
980 symbol_file: "libllndk.map.txt",
981 override_export_include_dirs: ["include_llndk"],
982 },
983 export_include_dirs: ["include"],
984 }
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800985
986 cc_library {
987 name: "libllndk_with_system_headers",
988 llndk: {
989 symbol_file: "libllndk.map.txt",
990 export_llndk_headers: ["libexternal_llndk_headers"],
991 export_headers_as_system: true,
992 },
993 export_include_dirs: ["include"],
994 export_system_include_dirs: ["include_system"],
995 }
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800996 `)
997 actual := result.ModuleVariantsForTests("libllndk")
998 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900999 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001000 actual = append(actual[:i], actual[i+1:]...)
1001 i--
1002 }
1003 }
1004 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001005 "android_vendor_arm64_armv8-a_shared",
1006 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001007 }
1008 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
1009
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001010 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00001011 android.AssertSame(t, "use Vendor API level for default stubs", "999999", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001012
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001013 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001014 t.Helper()
1015 m := result.ModuleForTests(module, variant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001016 f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001017 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1018 expectedDirs, f.IncludeDirs)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001019 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1020 expectedSystemDirs, f.SystemIncludeDirs)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001021 }
1022
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001023 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
1024 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
1025 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
1026 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
1027 []string{"include_system_llndk"}, "include_llndk")
1028 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
1029 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
1030 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
1031 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
1032 []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001033
1034 checkAbiLinkerIncludeDirs := func(module string) {
1035 t.Helper()
1036 coreModule := result.ModuleForTests(module, coreVariant)
1037 abiCheckFlags := ""
1038 for _, output := range coreModule.AllOutputs() {
1039 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1040 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1041 }
1042 }
1043 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001044 vendorInfo, _ := android.OtherModuleProvider(result, vendorModule, FlagExporterInfoProvider)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001045 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001046 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001047 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001048 }
1049 checkAbiLinkerIncludeDirs("libllndk")
1050 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1051 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001052 checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001053}
1054
Jiyong Parka46a4d52017-12-14 19:54:34 +09001055func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001056 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001057 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001058 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001059 name: "libllndk_headers",
1060 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001061 llndk: {
1062 llndk_headers: true,
1063 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001064 }
1065 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001066 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001067 llndk: {
1068 symbol_file: "libllndk.map.txt",
1069 export_llndk_headers: ["libllndk_headers"],
1070 }
Colin Cross0477b422020-10-13 18:43:54 -07001071 }
1072
1073 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001074 name: "libvendor",
1075 shared_libs: ["libllndk"],
1076 vendor: true,
1077 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001078 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001079 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001080 }
1081 `)
1082
1083 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001084 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001085 cflags := cc.Args["cFlags"]
1086 if !strings.Contains(cflags, "-Imy_include") {
1087 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1088 }
1089}
1090
Logan Chien43d34c32017-12-20 01:17:32 +08001091func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1092 actual := module.Properties.AndroidMkRuntimeLibs
1093 if !reflect.DeepEqual(actual, expected) {
1094 t.Errorf("incorrect runtime_libs for shared libs"+
1095 "\nactual: %v"+
1096 "\nexpected: %v",
1097 actual,
1098 expected,
1099 )
1100 }
1101}
1102
1103const runtimeLibAndroidBp = `
1104 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001105 name: "liball_available",
1106 vendor_available: true,
1107 product_available: true,
1108 no_libcrt : true,
1109 nocrt : true,
1110 system_shared_libs : [],
1111 }
1112 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001113 name: "libvendor_available1",
1114 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001115 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001116 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001117 nocrt : true,
1118 system_shared_libs : [],
1119 }
1120 cc_library {
1121 name: "libvendor_available2",
1122 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001123 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001124 target: {
1125 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001126 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001127 }
1128 },
Yi Konge7fe9912019-06-02 00:53:50 -07001129 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001130 nocrt : true,
1131 system_shared_libs : [],
1132 }
1133 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001134 name: "libproduct_vendor",
1135 product_specific: true,
1136 vendor_available: true,
1137 no_libcrt : true,
1138 nocrt : true,
1139 system_shared_libs : [],
1140 }
1141 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001142 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001143 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001144 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001145 nocrt : true,
1146 system_shared_libs : [],
1147 }
1148 cc_library {
1149 name: "libvendor1",
1150 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001151 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001152 nocrt : true,
1153 system_shared_libs : [],
1154 }
1155 cc_library {
1156 name: "libvendor2",
1157 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001158 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001159 no_libcrt : true,
1160 nocrt : true,
1161 system_shared_libs : [],
1162 }
1163 cc_library {
1164 name: "libproduct_available1",
1165 product_available: true,
1166 runtime_libs: ["liball_available"],
1167 no_libcrt : true,
1168 nocrt : true,
1169 system_shared_libs : [],
1170 }
1171 cc_library {
1172 name: "libproduct1",
1173 product_specific: true,
1174 no_libcrt : true,
1175 nocrt : true,
1176 system_shared_libs : [],
1177 }
1178 cc_library {
1179 name: "libproduct2",
1180 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001181 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001182 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001183 nocrt : true,
1184 system_shared_libs : [],
1185 }
1186`
1187
1188func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001189 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001190 ctx := testCc(t, runtimeLibAndroidBp)
1191
1192 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001193 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001194
Justin Yun8a2600c2020-12-07 12:44:03 +09001195 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1196 checkRuntimeLibs(t, []string{"liball_available"}, module)
1197
1198 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1199 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001200
1201 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001202 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001203
1204 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1205 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001206 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001207
Justin Yun8a2600c2020-12-07 12:44:03 +09001208 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1209 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001210
1211 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001212 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001213
1214 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1215 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001216 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001217
1218 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1219 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1220
1221 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001222 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001223}
1224
1225func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001226 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001227 ctx := testCc(t, runtimeLibAndroidBp)
1228
Colin Cross7113d202019-11-20 16:39:12 -08001229 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001230 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1231 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001232
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001233 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001234 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001235 checkRuntimeLibs(t, nil, module)
1236}
1237
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001238func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001239 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001240 actual := module.Properties.AndroidMkStaticLibs
1241 if !reflect.DeepEqual(actual, expected) {
1242 t.Errorf("incorrect static_libs"+
1243 "\nactual: %v"+
1244 "\nexpected: %v",
1245 actual,
1246 expected,
1247 )
1248 }
1249}
1250
1251const staticLibAndroidBp = `
1252 cc_library {
1253 name: "lib1",
1254 }
1255 cc_library {
1256 name: "lib2",
1257 static_libs: ["lib1"],
1258 }
1259`
1260
1261func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001262 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001263 ctx := testCc(t, staticLibAndroidBp)
1264
1265 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001266 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001267 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001268 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001269
1270 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001271 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001272 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1273 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001274 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001275}
1276
Jiyong Parkd08b6972017-09-26 10:50:54 +09001277var compilerFlagsTestCases = []struct {
1278 in string
1279 out bool
1280}{
1281 {
1282 in: "a",
1283 out: false,
1284 },
1285 {
1286 in: "-a",
1287 out: true,
1288 },
1289 {
1290 in: "-Ipath/to/something",
1291 out: false,
1292 },
1293 {
1294 in: "-isystempath/to/something",
1295 out: false,
1296 },
1297 {
1298 in: "--coverage",
1299 out: false,
1300 },
1301 {
1302 in: "-include a/b",
1303 out: true,
1304 },
1305 {
1306 in: "-include a/b c/d",
1307 out: false,
1308 },
1309 {
1310 in: "-DMACRO",
1311 out: true,
1312 },
1313 {
1314 in: "-DMAC RO",
1315 out: false,
1316 },
1317 {
1318 in: "-a -b",
1319 out: false,
1320 },
1321 {
1322 in: "-DMACRO=definition",
1323 out: true,
1324 },
1325 {
1326 in: "-DMACRO=defi nition",
1327 out: true, // TODO(jiyong): this should be false
1328 },
1329 {
1330 in: "-DMACRO(x)=x + 1",
1331 out: true,
1332 },
1333 {
1334 in: "-DMACRO=\"defi nition\"",
1335 out: true,
1336 },
1337}
1338
1339type mockContext struct {
1340 BaseModuleContext
1341 result bool
1342}
1343
1344func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1345 // CheckBadCompilerFlags calls this function when the flag should be rejected
1346 ctx.result = false
1347}
1348
1349func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001350 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001351 for _, testCase := range compilerFlagsTestCases {
1352 ctx := &mockContext{result: true}
1353 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1354 if ctx.result != testCase.out {
1355 t.Errorf("incorrect output:")
1356 t.Errorf(" input: %#v", testCase.in)
1357 t.Errorf(" expected: %#v", testCase.out)
1358 t.Errorf(" got: %#v", ctx.result)
1359 }
1360 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001361}
Jiyong Park374510b2018-03-19 18:23:01 +09001362
Jiyong Park37b25202018-07-11 10:49:27 +09001363func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001364 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001365 ctx := testCc(t, `
1366 cc_library_shared {
1367 name: "librecovery",
1368 recovery: true,
1369 }
1370 cc_library_shared {
1371 name: "librecovery32",
1372 recovery: true,
1373 compile_multilib:"32",
1374 }
Jiyong Park5baac542018-08-28 09:55:37 +09001375 cc_library_shared {
1376 name: "libHalInRecovery",
1377 recovery_available: true,
1378 vendor: true,
1379 }
Jiyong Park37b25202018-07-11 10:49:27 +09001380 `)
1381
1382 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001383 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001384 if len(variants) != 1 || !android.InList(arm64, variants) {
1385 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1386 }
1387
1388 variants = ctx.ModuleVariantsForTests("librecovery32")
1389 if android.InList(arm64, variants) {
1390 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1391 }
Jiyong Park5baac542018-08-28 09:55:37 +09001392
1393 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1394 if !recoveryModule.Platform() {
1395 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1396 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001397}
Jiyong Park5baac542018-08-28 09:55:37 +09001398
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001399func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001400 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001401 bp := `
1402 cc_prebuilt_test_library_shared {
1403 name: "test_lib",
1404 relative_install_path: "foo/bar/baz",
1405 srcs: ["srcpath/dontusethispath/baz.so"],
1406 }
1407
1408 cc_test {
1409 name: "main_test",
1410 data_libs: ["test_lib"],
1411 gtest: false,
1412 }
1413 `
1414
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001415 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001416
1417 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07001418 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
1419 module := testingModule.Module()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001420 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +00001421 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001422 if len(outputFiles) != 1 {
1423 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1424 }
1425 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001426 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001427 }
1428
1429 outputPath := outputFiles[0].String()
1430
1431 if !strings.HasSuffix(outputPath, "/main_test") {
1432 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1433 }
Yu Liue70976d2024-10-15 20:45:35 +00001434 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001435 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1436 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1437 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1438 }
1439}
1440
Jiyong Park7ed9de32018-10-15 22:25:07 +09001441func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001442 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001443 ctx := testCc(t, `
1444 cc_library_shared {
1445 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001446 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001447 stubs: {
1448 symbol_file: "foo.map.txt",
1449 versions: ["1", "2", "3"],
1450 },
1451 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001452
Jiyong Park7ed9de32018-10-15 22:25:07 +09001453 cc_library_shared {
1454 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001455 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001456 shared_libs: ["libFoo#1"],
1457 }`)
1458
1459 variants := ctx.ModuleVariantsForTests("libFoo")
1460 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001461 "android_arm64_armv8-a_shared",
1462 "android_arm64_armv8-a_shared_1",
1463 "android_arm64_armv8-a_shared_2",
1464 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001465 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001466 "android_arm_armv7-a-neon_shared",
1467 "android_arm_armv7-a-neon_shared_1",
1468 "android_arm_armv7-a-neon_shared_2",
1469 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001470 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001471 }
1472 variantsMismatch := false
1473 if len(variants) != len(expectedVariants) {
1474 variantsMismatch = true
1475 } else {
1476 for _, v := range expectedVariants {
1477 if !inList(v, variants) {
1478 variantsMismatch = false
1479 }
1480 }
1481 }
1482 if variantsMismatch {
1483 t.Errorf("variants of libFoo expected:\n")
1484 for _, v := range expectedVariants {
1485 t.Errorf("%q\n", v)
1486 }
1487 t.Errorf(", but got:\n")
1488 for _, v := range variants {
1489 t.Errorf("%q\n", v)
1490 }
1491 }
1492
Colin Cross7113d202019-11-20 16:39:12 -08001493 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001494 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001495 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001496 if !strings.Contains(libFlags, libFoo1StubPath) {
1497 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1498 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001499
Colin Cross7113d202019-11-20 16:39:12 -08001500 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001501 cFlags := libBarCompileRule.Args["cFlags"]
1502 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1503 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1504 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1505 }
Jiyong Park37b25202018-07-11 10:49:27 +09001506}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001507
Jooyung Hanb04a4992020-03-13 18:57:35 +09001508func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001509 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001510 for _, tc := range []struct{ moduleName, expected string }{
1511 {"libc", "__LIBC_API__"},
1512 {"libfoo", "__LIBFOO_API__"},
1513 {"libfoo@1", "__LIBFOO_1_API__"},
1514 {"libfoo-v1", "__LIBFOO_V1_API__"},
1515 {"libfoo.v1", "__LIBFOO_V1_API__"},
1516 } {
1517 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1518 }
1519}
1520
Liz Kammer83cf81b2022-09-22 08:24:20 -04001521func pathsToBase(paths android.Paths) []string {
1522 var ret []string
1523 for _, p := range paths {
1524 ret = append(ret, p.Base())
1525 }
1526 return ret
1527}
1528
1529func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001530 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001531 ctx := testCc(t, `
1532 cc_library_static {
1533 name: "foo",
1534 srcs: ["foo.c"],
1535 }
1536
1537 cc_library_static {
1538 name: "bar",
1539 srcs: ["bar.c"],
1540 }
1541
1542 cc_library_shared {
1543 name: "qux",
1544 srcs: ["qux.c"],
1545 }
1546
1547 cc_library_static {
1548 name: "baz",
1549 srcs: ["baz.c"],
1550 static_libs: ["foo"],
1551 shared_libs: ["qux"],
1552 whole_static_libs: ["bar"],
1553 }`)
1554
1555 variant := "android_arm64_armv8-a_static"
1556 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1557
1558 // For static libraries, the object files of a whole static dep are included in the archive
1559 // directly
1560 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1561 t.Errorf("Expected input objects %q, got %q", w, g)
1562 }
1563
1564 // non whole static dependencies are not linked into the archive
1565 if len(arRule.Implicits) > 0 {
1566 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1567 }
1568}
1569
1570func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001571 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001572 ctx := testCc(t, `
1573 cc_library_static {
1574 name: "foo",
1575 srcs: ["foo.c"],
1576 }
1577
1578 cc_library_static {
1579 name: "bar",
1580 srcs: ["bar.c"],
1581 }
1582
1583 cc_library_shared {
1584 name: "qux",
1585 srcs: ["qux.c"],
1586 }
1587
1588 cc_library_shared {
1589 name: "baz",
1590 srcs: ["baz.c"],
1591 static_libs: ["foo"],
1592 shared_libs: ["qux"],
1593 whole_static_libs: ["bar"],
1594 }`)
1595
1596 variant := "android_arm64_armv8-a_shared"
1597 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1598 libFlags := linkRule.Args["libFlags"]
1599 // When dynamically linking, we expect static dependencies to be found on the command line
1600 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1601 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1602 }
1603 // When dynamically linking, we expect whole static dependencies to be found on the command line
1604 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1605 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1606 }
1607
1608 // When dynamically linking, we expect shared dependencies to be found on the command line
1609 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1610 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1611 }
1612
1613 // We should only have the objects from the shared library srcs, not the whole static dependencies
1614 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1615 t.Errorf("Expected input objects %q, got %q", w, g)
1616 }
1617}
1618
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001619func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001620 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001621 ctx := testCc(t, `
1622 cc_binary {
1623 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001624 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001625 static_executable: true,
1626 }`)
1627
Colin Cross7113d202019-11-20 16:39:12 -08001628 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001629 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1630 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001631 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001632 for _, lib := range systemStaticLibs {
1633 if !strings.Contains(libFlags, lib) {
1634 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1635 }
1636 }
1637 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1638 for _, lib := range systemSharedLibs {
1639 if strings.Contains(libFlags, lib) {
1640 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1641 }
1642 }
1643}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001644
1645func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001646 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001647 ctx := testCc(t, `
1648 cc_binary {
1649 name: "mybin",
1650 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001651 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001652 static_executable: true,
1653 stl: "none",
1654 }
1655
1656 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001657 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001658 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001659 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001660 stl: "none",
1661 }
1662
1663 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001664 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001665 srcs: ["foo.c"],
1666 stl: "none",
1667 stubs: {
1668 versions: ["1"],
1669 },
1670 }`)
1671
Colin Cross0de8a1e2020-09-18 14:15:30 -07001672 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1673 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001674 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001675
1676 if !reflect.DeepEqual(actual, expected) {
1677 t.Errorf("staticDeps orderings were not propagated correctly"+
1678 "\nactual: %v"+
1679 "\nexpected: %v",
1680 actual,
1681 expected,
1682 )
1683 }
1684}
Jooyung Han38002912019-05-16 04:01:54 +09001685
Jooyung Hand48f3c32019-08-23 11:18:57 +09001686func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001687 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001688 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1689 cc_library {
1690 name: "libA",
1691 srcs: ["foo.c"],
1692 shared_libs: ["libB"],
1693 stl: "none",
1694 }
1695
1696 cc_library {
1697 name: "libB",
1698 srcs: ["foo.c"],
1699 enabled: false,
1700 stl: "none",
1701 }
1702 `)
1703}
1704
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001705func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1706 bp := `
1707 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001708 name: "test_afl_fuzz_target",
1709 srcs: ["foo.c"],
1710 host_supported: true,
1711 static_libs: [
1712 "afl_fuzz_static_lib",
1713 ],
1714 shared_libs: [
1715 "afl_fuzz_shared_lib",
1716 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001717 fuzzing_frameworks: {
1718 afl: true,
1719 libfuzzer: false,
1720 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001721 }
1722 cc_library {
1723 name: "afl_fuzz_static_lib",
1724 host_supported: true,
1725 srcs: ["static_file.c"],
1726 }
1727 cc_library {
1728 name: "libfuzzer_only_static_lib",
1729 host_supported: true,
1730 srcs: ["static_file.c"],
1731 }
1732 cc_library {
1733 name: "afl_fuzz_shared_lib",
1734 host_supported: true,
1735 srcs: ["shared_file.c"],
1736 static_libs: [
1737 "second_static_lib",
1738 ],
1739 }
1740 cc_library_headers {
1741 name: "libafl_headers",
1742 vendor_available: true,
1743 host_supported: true,
1744 export_include_dirs: [
1745 "include",
1746 "instrumentation",
1747 ],
1748 }
1749 cc_object {
1750 name: "afl-compiler-rt",
1751 vendor_available: true,
1752 host_supported: true,
1753 cflags: [
1754 "-fPIC",
1755 ],
1756 srcs: [
1757 "instrumentation/afl-compiler-rt.o.c",
1758 ],
1759 }
1760 cc_library {
1761 name: "second_static_lib",
1762 host_supported: true,
1763 srcs: ["second_file.c"],
1764 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001765 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001766 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001767 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001768 srcs: [
1769 "aflpp_driver.c",
1770 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001771 }`
1772
1773 testEnv := map[string]string{
1774 "FUZZ_FRAMEWORK": "AFL",
1775 }
1776
1777 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001778
1779 checkPcGuardFlag := func(
1780 modName string, variantName string, shouldHave bool) {
1781 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1782
1783 cFlags, ok := cc.Args["cFlags"]
1784 if !ok {
1785 t.Errorf("Could not find cFlags for module %s and variant %s",
1786 modName, variantName)
1787 }
1788
1789 if strings.Contains(
1790 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1791 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1792 "Test failed for module %s and variant %s",
1793 !shouldHave, shouldHave, modName, variantName)
1794 }
1795 }
1796
Cory Barkera1da26f2022-06-07 20:12:06 +00001797 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001798 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001799
1800 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001801 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001802 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001803
1804 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001805 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001806 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001807
1808 ctx.ModuleForTests("afl_fuzz_shared_lib",
1809 "android_arm64_armv8-a_shared").Rule("cc")
1810 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001811 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1812}
1813
1814func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001815 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001816 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1817}
1818
1819func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001820 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001821 if runtime.GOOS != "linux" {
1822 t.Skip("requires linux")
1823 }
1824
1825 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001826}
1827
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001828// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1829// correctly.
1830func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001831 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001832 ctx := testCc(t, `
1833 cc_fuzz {
1834 name: "fuzz_smoke_test",
1835 srcs: ["foo.c"],
1836 }`)
1837
Paul Duffin075c4172019-12-19 19:06:13 +00001838 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001839 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1840}
1841
Jooyung Han38002912019-05-16 04:01:54 +09001842func assertString(t *testing.T, got, expected string) {
1843 t.Helper()
1844 if got != expected {
1845 t.Errorf("expected %q got %q", expected, got)
1846 }
1847}
1848
1849func assertArrayString(t *testing.T, got, expected []string) {
1850 t.Helper()
1851 if len(got) != len(expected) {
1852 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1853 return
1854 }
1855 for i := range got {
1856 if got[i] != expected[i] {
1857 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1858 i, expected[i], expected, got[i], got)
1859 return
1860 }
1861 }
1862}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001863
Jooyung Han0302a842019-10-30 18:43:49 +09001864func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1865 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001866 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001867}
1868
Colin Crosse1bb5d02019-09-24 14:55:04 -07001869func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001870 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001871 ctx := testCc(t, `
1872 cc_defaults {
1873 name: "defaults",
1874 srcs: ["foo.c"],
1875 static: {
1876 srcs: ["bar.c"],
1877 },
1878 shared: {
1879 srcs: ["baz.c"],
1880 },
1881 }
1882
1883 cc_library_static {
1884 name: "libstatic",
1885 defaults: ["defaults"],
1886 }
1887
1888 cc_library_shared {
1889 name: "libshared",
1890 defaults: ["defaults"],
1891 }
1892
1893 cc_library {
1894 name: "libboth",
1895 defaults: ["defaults"],
1896 }
1897
1898 cc_binary {
1899 name: "binary",
1900 defaults: ["defaults"],
1901 }`)
1902
Colin Cross7113d202019-11-20 16:39:12 -08001903 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001904 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1905 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
1906 }
Colin Cross7113d202019-11-20 16:39:12 -08001907 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001908 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1909 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
1910 }
Colin Cross7113d202019-11-20 16:39:12 -08001911 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001912 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
1913 t.Errorf("binary ld rule wanted %q, got %q", w, g)
1914 }
1915
Colin Cross7113d202019-11-20 16:39:12 -08001916 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001917 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1918 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
1919 }
Colin Cross7113d202019-11-20 16:39:12 -08001920 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001921 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1922 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
1923 }
1924}
Colin Crosseabaedd2020-02-06 17:01:55 -08001925
1926func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001927 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08001928 bp := `
1929 cc_defaults {
1930 name: "libfoo_defaults",
1931 srcs: ["foo.c"],
1932 cppflags: ["-DFOO"],
1933 product_variables: {
1934 debuggable: {
1935 cppflags: ["-DBAR"],
1936 },
1937 },
1938 }
1939
1940 cc_library {
1941 name: "libfoo",
1942 defaults: ["libfoo_defaults"],
1943 }
1944 `
1945
Paul Duffin8567f222021-03-23 00:02:06 +00001946 result := android.GroupFixturePreparers(
1947 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001948 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08001949
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001950 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1951 variables.Debuggable = BoolPtr(true)
1952 }),
1953 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08001954
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001955 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00001956 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08001957}
Colin Crosse4f6eba2020-09-22 18:11:25 -07001958
1959func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
1960 t.Parallel()
1961 bp := `
1962 cc_library_static {
1963 name: "libfoo",
1964 srcs: ["foo.c"],
1965 whole_static_libs: ["libbar"],
1966 }
1967
1968 cc_library_static {
1969 name: "libbar",
1970 whole_static_libs: ["libmissing"],
1971 }
1972 `
1973
Paul Duffin8567f222021-03-23 00:02:06 +00001974 result := android.GroupFixturePreparers(
1975 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001976 android.PrepareForTestWithAllowMissingDependencies,
1977 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07001978
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001979 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00001980 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07001981
Paul Duffine84b1332021-03-12 11:59:43 +00001982 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07001983
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001984 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00001985 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07001986}
Colin Crosse9fe2942020-11-10 18:12:15 -08001987
1988func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001989 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08001990 bp := `
1991 cc_binary {
1992 name: "bin",
1993 host_supported: true,
1994 shared_libs: ["libshared"],
1995 runtime_libs: ["libruntime"],
1996 srcs: [":gen"],
1997 }
1998
1999 cc_library_shared {
2000 name: "libshared",
2001 host_supported: true,
2002 shared_libs: ["libtransitive"],
2003 }
2004
2005 cc_library_shared {
2006 name: "libtransitive",
2007 host_supported: true,
2008 }
2009
2010 cc_library_shared {
2011 name: "libruntime",
2012 host_supported: true,
2013 }
2014
2015 cc_binary_host {
2016 name: "tool",
2017 srcs: ["foo.cpp"],
2018 }
2019
2020 genrule {
2021 name: "gen",
2022 tools: ["tool"],
2023 out: ["gen.cpp"],
2024 cmd: "$(location tool) $(out)",
2025 }
2026 `
2027
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002028 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002029 ctx := testCcWithConfig(t, config)
2030
2031 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2032 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2033 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2034 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2035 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2036
2037 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2038 t.Errorf("expected host bin dependency %q, got %q", w, g)
2039 }
2040
2041 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2042 t.Errorf("expected host bin dependency %q, got %q", w, g)
2043 }
2044
2045 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2046 t.Errorf("expected host bin dependency %q, got %q", w, g)
2047 }
2048
2049 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2050 t.Errorf("expected host bin dependency %q, got %q", w, g)
2051 }
2052
2053 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2054 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2055 }
2056
2057 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2058 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2059 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2060 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2061
2062 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2063 t.Errorf("expected device bin dependency %q, got %q", w, g)
2064 }
2065
2066 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2067 t.Errorf("expected device bin dependency %q, got %q", w, g)
2068 }
2069
2070 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2071 t.Errorf("expected device bin dependency %q, got %q", w, g)
2072 }
2073
2074 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2075 t.Errorf("expected device bin dependency %q, got %q", w, g)
2076 }
2077
2078 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2079 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2080 }
2081
2082}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002083
2084func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002085 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002086 ctx := testCc(t, `
2087 cc_library_shared {
2088 name: "libclient",
2089 srcs: ["foo.c"],
2090 shared_libs: ["libfoo#1"],
2091 }
2092
2093 cc_library_shared {
2094 name: "libfoo",
2095 srcs: ["foo.c"],
2096 shared_libs: ["libbar"],
2097 export_shared_lib_headers: ["libbar"],
2098 stubs: {
2099 symbol_file: "foo.map.txt",
2100 versions: ["1", "2", "3"],
2101 },
2102 }
2103
2104 cc_library_shared {
2105 name: "libbar",
2106 export_include_dirs: ["include/libbar"],
2107 srcs: ["foo.c"],
2108 }`)
2109
2110 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2111
2112 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2113 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2114 }
2115}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002116
Vinh Tran09581952023-05-16 16:03:20 -04002117func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002118 t.Parallel()
2119 ctx := android.GroupFixturePreparers(
2120 prepareForCcTest,
2121 aidl_library.PrepareForTestWithAidlLibrary,
2122 android.MockFS{
2123 "package_bar/Android.bp": []byte(`
2124 aidl_library {
2125 name: "bar",
2126 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002127 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002128 strip_import_prefix: "x",
2129 }
2130 `)}.AddToFixture(),
2131 android.MockFS{
2132 "package_foo/Android.bp": []byte(`
2133 aidl_library {
2134 name: "foo",
2135 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002136 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002137 strip_import_prefix: "a",
2138 deps: ["bar"],
2139 }
2140 cc_library {
2141 name: "libfoo",
2142 aidl: {
2143 libs: ["foo"],
2144 }
2145 }
2146 `),
2147 }.AddToFixture(),
2148 ).RunTest(t).TestContext
2149
2150 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002151
2152 android.AssertPathsRelativeToTopEquals(
2153 t,
2154 "aidl headers",
2155 []string{
2156 "package_bar/x/HeaderBar.aidl",
2157 "package_foo/a/HeaderFoo.aidl",
2158 "package_foo/a/b/Foo.aidl",
2159 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2160 },
2161 libfoo.Rule("aidl_library").Implicits,
2162 )
2163
Colin Crossf61d03d2023-11-02 16:56:39 -07002164 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002165 aidlCommand := manifest.Commands[0].GetCommand()
2166
2167 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2168 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2169 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2170 }
2171
2172 outputs := strings.Join(libfoo.AllOutputs(), " ")
2173
Vinh Tran09581952023-05-16 16:03:20 -04002174 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2175 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2176 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002177 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2178 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002179 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2180 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2181 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002182 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2183}
2184
Jooyung Hane197d8b2021-01-05 10:33:16 +09002185func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002186 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002187 ctx := android.GroupFixturePreparers(
2188 prepareForCcTest,
2189 aidl_library.PrepareForTestWithAidlLibrary,
2190 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002191 cc_library {
2192 name: "libfoo",
2193 srcs: ["a/Foo.aidl"],
2194 aidl: { flags: ["-Werror"], },
2195 }
2196 `)
2197
2198 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002199 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002200 aidlCommand := manifest.Commands[0].GetCommand()
2201 expectedAidlFlag := "-Werror"
2202 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2203 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2204 }
2205}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002206
Jooyung Han07f70c02021-11-06 07:08:45 +09002207func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002208 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002209 for _, tc := range []struct {
2210 name string
2211 sdkVersion string
2212 variant string
2213 expected string
2214 }{
2215 {
2216 name: "default is current",
2217 sdkVersion: "",
2218 variant: "android_arm64_armv8-a_static",
2219 expected: "platform_apis",
2220 },
2221 {
2222 name: "use sdk_version",
2223 sdkVersion: `sdk_version: "29"`,
2224 variant: "android_arm64_armv8-a_static",
2225 expected: "platform_apis",
2226 },
2227 {
2228 name: "use sdk_version(sdk variant)",
2229 sdkVersion: `sdk_version: "29"`,
2230 variant: "android_arm64_armv8-a_sdk_static",
2231 expected: "29",
2232 },
2233 {
2234 name: "use min_sdk_version",
2235 sdkVersion: `min_sdk_version: "29"`,
2236 variant: "android_arm64_armv8-a_static",
2237 expected: "29",
2238 },
2239 } {
2240 t.Run(tc.name, func(t *testing.T) {
2241 ctx := testCc(t, `
2242 cc_library {
2243 name: "libfoo",
2244 stl: "none",
2245 srcs: ["a/Foo.aidl"],
2246 `+tc.sdkVersion+`
2247 }
2248 `)
2249 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002250 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002251 aidlCommand := manifest.Commands[0].GetCommand()
2252 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2253 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2254 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2255 }
2256 })
2257 }
2258}
2259
Vinh Tran09581952023-05-16 16:03:20 -04002260func TestInvalidAidlProp(t *testing.T) {
2261 t.Parallel()
2262
2263 testCases := []struct {
2264 description string
2265 bp string
2266 }{
2267 {
2268 description: "Invalid use of aidl.libs and aidl.include_dirs",
2269 bp: `
2270 cc_library {
2271 name: "foo",
2272 aidl: {
2273 libs: ["foo_aidl"],
2274 include_dirs: ["bar/include"],
2275 }
2276 }
2277 `,
2278 },
2279 {
2280 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2281 bp: `
2282 cc_library {
2283 name: "foo",
2284 aidl: {
2285 libs: ["foo_aidl"],
2286 local_include_dirs: ["include"],
2287 }
2288 }
2289 `,
2290 },
2291 }
2292
2293 for _, testCase := range testCases {
2294 t.Run(testCase.description, func(t *testing.T) {
2295 bp := `
2296 aidl_library {
2297 name: "foo_aidl",
2298 srcs: ["Foo.aidl"],
2299 } ` + testCase.bp
2300 android.GroupFixturePreparers(
2301 prepareForCcTest,
2302 aidl_library.PrepareForTestWithAidlLibrary.
2303 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2304 ).RunTestWithBp(t, bp)
2305 })
2306 }
2307}
2308
Jiyong Parka008fb02021-03-16 17:15:53 +09002309func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002310 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002311 ctx := testCc(t, `
2312 cc_library_shared {
2313 name: "libfoo",
2314 srcs: ["foo.c"],
2315 min_sdk_version: "29",
2316 }`)
2317
2318 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2319 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2320}
2321
Vinh Tranf1924742022-06-24 16:40:11 -04002322func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002323 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002324 bp := `
2325 cc_library_shared {
2326 name: "libfoo",
2327 srcs: ["foo.c"],
2328 min_sdk_version: "S",
2329 }
2330 `
2331 result := android.GroupFixturePreparers(
2332 prepareForCcTest,
2333 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2334 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2335 }),
2336 ).RunTestWithBp(t, bp)
2337 ctx := result.TestContext
2338 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2339 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2340}
2341
Paul Duffin3cb603e2021-02-19 13:57:10 +00002342func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002343 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002344
2345 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2346 // embedded newline characters alone.
2347 trimIndentingSpaces := func(s string) string {
2348 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2349 }
2350
2351 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2352 t.Helper()
2353 expected = trimIndentingSpaces(expected)
2354 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2355 if expected != actual {
2356 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2357 }
2358 }
2359
2360 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2361
2362 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2363 t.Helper()
Yu Liu663e4502024-08-12 18:23:59 +00002364 exported, _ := android.OtherModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002365 name := module.Name()
2366
2367 for _, checker := range checkers {
2368 checker(t, name, exported)
2369 }
2370 }
2371
2372 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2373 return func(t *testing.T, name string, exported FlagExporterInfo) {
2374 t.Helper()
2375 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2376 }
2377 }
2378
2379 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2380 return func(t *testing.T, name string, exported FlagExporterInfo) {
2381 t.Helper()
2382 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2383 }
2384 }
2385
2386 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2387 return func(t *testing.T, name string, exported FlagExporterInfo) {
2388 t.Helper()
2389 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2390 }
2391 }
2392
2393 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2394 return func(t *testing.T, name string, exported FlagExporterInfo) {
2395 t.Helper()
2396 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2397 }
2398 }
2399
2400 genRuleModules := `
2401 genrule {
2402 name: "genrule_foo",
2403 cmd: "generate-foo",
2404 out: [
2405 "generated_headers/foo/generated_header.h",
2406 ],
2407 export_include_dirs: [
2408 "generated_headers",
2409 ],
2410 }
2411
2412 genrule {
2413 name: "genrule_bar",
2414 cmd: "generate-bar",
2415 out: [
2416 "generated_headers/bar/generated_header.h",
2417 ],
2418 export_include_dirs: [
2419 "generated_headers",
2420 ],
2421 }
2422 `
2423
2424 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2425 ctx := testCc(t, genRuleModules+`
2426 cc_library {
2427 name: "libfoo",
2428 srcs: ["foo.c"],
2429 export_include_dirs: ["foo/standard"],
2430 export_system_include_dirs: ["foo/system"],
2431 generated_headers: ["genrule_foo"],
2432 export_generated_headers: ["genrule_foo"],
2433 }
2434
2435 cc_library {
2436 name: "libbar",
2437 srcs: ["bar.c"],
2438 shared_libs: ["libfoo"],
2439 export_include_dirs: ["bar/standard"],
2440 export_system_include_dirs: ["bar/system"],
2441 generated_headers: ["genrule_bar"],
2442 export_generated_headers: ["genrule_bar"],
2443 }
2444 `)
2445 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2446 checkIncludeDirs(t, ctx, foo,
2447 expectedIncludeDirs(`
2448 foo/standard
2449 .intermediates/genrule_foo/gen/generated_headers
2450 `),
2451 expectedSystemIncludeDirs(`foo/system`),
2452 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2453 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2454 )
2455
2456 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2457 checkIncludeDirs(t, ctx, bar,
2458 expectedIncludeDirs(`
2459 bar/standard
2460 .intermediates/genrule_bar/gen/generated_headers
2461 `),
2462 expectedSystemIncludeDirs(`bar/system`),
2463 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2464 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2465 )
2466 })
2467
2468 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2469 ctx := testCc(t, genRuleModules+`
2470 cc_library {
2471 name: "libfoo",
2472 srcs: ["foo.c"],
2473 export_include_dirs: ["foo/standard"],
2474 export_system_include_dirs: ["foo/system"],
2475 generated_headers: ["genrule_foo"],
2476 export_generated_headers: ["genrule_foo"],
2477 }
2478
2479 cc_library {
2480 name: "libbar",
2481 srcs: ["bar.c"],
2482 whole_static_libs: ["libfoo"],
2483 export_include_dirs: ["bar/standard"],
2484 export_system_include_dirs: ["bar/system"],
2485 generated_headers: ["genrule_bar"],
2486 export_generated_headers: ["genrule_bar"],
2487 }
2488 `)
2489 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2490 checkIncludeDirs(t, ctx, foo,
2491 expectedIncludeDirs(`
2492 foo/standard
2493 .intermediates/genrule_foo/gen/generated_headers
2494 `),
2495 expectedSystemIncludeDirs(`foo/system`),
2496 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2497 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2498 )
2499
2500 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2501 checkIncludeDirs(t, ctx, bar,
2502 expectedIncludeDirs(`
2503 bar/standard
2504 foo/standard
2505 .intermediates/genrule_foo/gen/generated_headers
2506 .intermediates/genrule_bar/gen/generated_headers
2507 `),
2508 expectedSystemIncludeDirs(`
2509 bar/system
2510 foo/system
2511 `),
2512 expectedGeneratedHeaders(`
2513 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2514 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2515 `),
2516 expectedOrderOnlyDeps(`
2517 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2518 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2519 `),
2520 )
2521 })
2522
Paul Duffin3cb603e2021-02-19 13:57:10 +00002523 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002524 ctx := android.GroupFixturePreparers(
2525 prepareForCcTest,
2526 aidl_library.PrepareForTestWithAidlLibrary,
2527 ).RunTestWithBp(t, `
2528 aidl_library {
2529 name: "libfoo_aidl",
2530 srcs: ["x/y/Bar.aidl"],
2531 strip_import_prefix: "x",
2532 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002533 cc_library_shared {
2534 name: "libfoo",
2535 srcs: [
2536 "foo.c",
2537 "b.aidl",
2538 "a.proto",
2539 ],
2540 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002541 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002542 export_aidl_headers: true,
2543 }
2544 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002545 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002546 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2547 checkIncludeDirs(t, ctx, foo,
2548 expectedIncludeDirs(`
2549 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002550 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002551 `),
2552 expectedSystemIncludeDirs(``),
2553 expectedGeneratedHeaders(`
2554 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2555 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2556 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002557 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2558 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2559 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002560 `),
2561 expectedOrderOnlyDeps(`
2562 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2563 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2564 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002565 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2566 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2567 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002568 `),
2569 )
2570 })
2571
Paul Duffin3cb603e2021-02-19 13:57:10 +00002572 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2573 ctx := testCc(t, genRuleModules+`
2574 cc_library_shared {
2575 name: "libfoo",
2576 srcs: [
2577 "foo.c",
2578 "b.aidl",
2579 "a.proto",
2580 ],
2581 proto: {
2582 export_proto_headers: true,
2583 }
2584 }
2585 `)
2586 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2587 checkIncludeDirs(t, ctx, foo,
2588 expectedIncludeDirs(`
2589 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2590 `),
2591 expectedSystemIncludeDirs(``),
2592 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002593 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2594 `),
2595 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002596 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2597 `),
2598 )
2599 })
2600
Paul Duffin33056e82021-02-19 13:49:08 +00002601 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002602 ctx := testCc(t, genRuleModules+`
2603 cc_library_shared {
2604 name: "libfoo",
2605 srcs: [
2606 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002607 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002608 "b.aidl",
2609 "a.proto",
2610 ],
2611 }
2612 `)
2613 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2614 checkIncludeDirs(t, ctx, foo,
2615 expectedIncludeDirs(`
2616 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2617 `),
2618 expectedSystemIncludeDirs(``),
2619 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002620 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002621 `),
2622 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002623 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2624 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002625 `),
2626 )
2627 })
2628}
Colin Crossae628182021-06-14 16:52:28 -07002629
2630func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002631 t.Parallel()
Colin Cross0e097dd2024-10-17 11:41:28 -07002632
2633 expectedPlatformFlags := []string{
2634 "-nostdlibinc",
2635 }
2636
Liz Kammer08572c62021-09-30 10:11:04 -04002637 baseExpectedFlags := []string{
2638 "${config.ArmThumbCflags}",
2639 "${config.ArmCflags}",
2640 "${config.CommonGlobalCflags}",
2641 "${config.DeviceGlobalCflags}",
2642 "${config.ExternalCflags}",
2643 "${config.ArmToolchainCflags}",
2644 "${config.ArmArmv7ANeonCflags}",
2645 "${config.ArmGenericCflags}",
Colin Crossdd81e672024-10-17 14:01:12 -07002646 }
2647
2648 expectedTargetNDKFlags := []string{
Liz Kammer08572c62021-09-30 10:11:04 -04002649 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002650 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002651 }
2652
Colin Crossdd81e672024-10-17 14:01:12 -07002653 expectedTargetPlatformFlags := []string{
2654 "-target",
2655 "armv7a-linux-androideabi10000",
2656 }
2657
Liz Kammer08572c62021-09-30 10:11:04 -04002658 expectedIncludes := []string{
2659 "external/foo/android_arm_export_include_dirs",
2660 "external/foo/lib32_export_include_dirs",
2661 "external/foo/arm_export_include_dirs",
2662 "external/foo/android_export_include_dirs",
2663 "external/foo/linux_export_include_dirs",
2664 "external/foo/export_include_dirs",
2665 "external/foo/android_arm_local_include_dirs",
2666 "external/foo/lib32_local_include_dirs",
2667 "external/foo/arm_local_include_dirs",
2668 "external/foo/android_local_include_dirs",
2669 "external/foo/linux_local_include_dirs",
2670 "external/foo/local_include_dirs",
2671 "external/foo",
2672 "external/foo/libheader1",
2673 "external/foo/libheader2",
2674 "external/foo/libwhole1",
2675 "external/foo/libwhole2",
2676 "external/foo/libstatic1",
2677 "external/foo/libstatic2",
2678 "external/foo/libshared1",
2679 "external/foo/libshared2",
2680 "external/foo/liblinux",
2681 "external/foo/libandroid",
2682 "external/foo/libarm",
2683 "external/foo/lib32",
2684 "external/foo/libandroid_arm",
Colin Crossdd81e672024-10-17 14:01:12 -07002685 }
2686
2687 expectedNDKSTLIncludes := []string{
Ryan Prichard2a69eb62024-07-30 01:58:54 +00002688 "defaults/cc/common/ndk_libc++_shared_include_dirs",
Liz Kammer08572c62021-09-30 10:11:04 -04002689 }
2690
2691 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2692 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2693
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002694 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002695 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002696 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002697
Colin Cross0e097dd2024-10-17 11:41:28 -07002698 lastNDKFlags := []string{
2699 "--sysroot",
2700 "out/soong/ndk/sysroot",
Liz Kammer08572c62021-09-30 10:11:04 -04002701 }
2702
Colin Crossdd81e672024-10-17 14:01:12 -07002703 lastPlatformIncludes := []string{
2704 "${config.CommonGlobalIncludes}",
Liz Kammer08572c62021-09-30 10:11:04 -04002705 }
2706
2707 testCases := []struct {
Colin Crossdd81e672024-10-17 14:01:12 -07002708 name string
2709 src string
2710 expectedNDK []string
2711 expectedPlatform []string
Liz Kammer08572c62021-09-30 10:11:04 -04002712 }{
2713 {
Colin Crossdd81e672024-10-17 14:01:12 -07002714 name: "c",
2715 src: "foo.c",
2716 expectedNDK: slices.Concat(
2717 baseExpectedFlags,
2718 expectedTargetNDKFlags,
2719 conly,
2720 expectedIncludes,
2721 expectedNDKSTLIncludes,
2722 cflags,
2723 cstd,
Colin Cross0e097dd2024-10-17 11:41:28 -07002724 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002725 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2726 ),
2727 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002728 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002729 baseExpectedFlags,
2730 expectedTargetPlatformFlags,
2731 conly,
2732 expectedIncludes,
2733 cflags,
2734 cstd,
2735 lastPlatformIncludes,
2736 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2737 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002738 },
2739 {
Colin Crossdd81e672024-10-17 14:01:12 -07002740 name: "cc",
2741 src: "foo.cc",
2742 expectedNDK: slices.Concat(
2743 baseExpectedFlags,
2744 expectedTargetNDKFlags,
2745 cppOnly,
2746 expectedIncludes,
2747 expectedNDKSTLIncludes,
2748 cflags,
2749 cppstd,
Colin Cross0e097dd2024-10-17 11:41:28 -07002750 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002751 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2752 ),
2753 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002754 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002755 baseExpectedFlags,
2756 expectedTargetPlatformFlags,
2757 cppOnly,
2758 expectedIncludes,
2759 cflags,
2760 cppstd,
2761 lastPlatformIncludes,
2762 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2763 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002764 },
2765 {
Colin Crossdd81e672024-10-17 14:01:12 -07002766 name: "assemble",
2767 src: "foo.s",
2768 expectedNDK: slices.Concat(
2769 baseExpectedFlags,
2770 expectedTargetNDKFlags,
2771 []string{"${config.CommonGlobalAsflags}"},
2772 expectedIncludes,
2773 expectedNDKSTLIncludes,
Colin Cross0e097dd2024-10-17 11:41:28 -07002774 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002775 ),
2776 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002777 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002778 baseExpectedFlags,
2779 expectedTargetPlatformFlags,
2780 []string{"${config.CommonGlobalAsflags}"},
2781 expectedIncludes,
2782 lastPlatformIncludes,
2783 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002784 },
2785 }
2786
2787 for _, tc := range testCases {
2788 t.Run(tc.name, func(t *testing.T) {
2789 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002790 cc_library {
2791 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002792 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002793 cflags: ["-std=candcpp"],
2794 conlyflags: ["-std=conly"],
2795 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002796 local_include_dirs: ["local_include_dirs"],
2797 export_include_dirs: ["export_include_dirs"],
2798 export_system_include_dirs: ["export_system_include_dirs"],
2799 static_libs: ["libstatic1", "libstatic2"],
2800 whole_static_libs: ["libwhole1", "libwhole2"],
2801 shared_libs: ["libshared1", "libshared2"],
2802 header_libs: ["libheader1", "libheader2"],
2803 target: {
2804 android: {
2805 shared_libs: ["libandroid"],
2806 local_include_dirs: ["android_local_include_dirs"],
2807 export_include_dirs: ["android_export_include_dirs"],
2808 },
2809 android_arm: {
2810 shared_libs: ["libandroid_arm"],
2811 local_include_dirs: ["android_arm_local_include_dirs"],
2812 export_include_dirs: ["android_arm_export_include_dirs"],
2813 },
2814 linux: {
2815 shared_libs: ["liblinux"],
2816 local_include_dirs: ["linux_local_include_dirs"],
2817 export_include_dirs: ["linux_export_include_dirs"],
2818 },
2819 },
2820 multilib: {
2821 lib32: {
2822 shared_libs: ["lib32"],
2823 local_include_dirs: ["lib32_local_include_dirs"],
2824 export_include_dirs: ["lib32_export_include_dirs"],
2825 },
2826 },
2827 arch: {
2828 arm: {
2829 shared_libs: ["libarm"],
2830 local_include_dirs: ["arm_local_include_dirs"],
2831 export_include_dirs: ["arm_export_include_dirs"],
2832 },
2833 },
2834 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002835 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002836 }
2837
2838 cc_library_headers {
2839 name: "libheader1",
2840 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002841 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002842 stl: "none",
2843 }
2844
2845 cc_library_headers {
2846 name: "libheader2",
2847 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002848 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002849 stl: "none",
2850 }
Liz Kammer08572c62021-09-30 10:11:04 -04002851 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002852
Liz Kammer08572c62021-09-30 10:11:04 -04002853 libs := []string{
2854 "libstatic1",
2855 "libstatic2",
2856 "libwhole1",
2857 "libwhole2",
2858 "libshared1",
2859 "libshared2",
2860 "libandroid",
2861 "libandroid_arm",
2862 "liblinux",
2863 "lib32",
2864 "libarm",
2865 }
Colin Crossae628182021-06-14 16:52:28 -07002866
Liz Kammer08572c62021-09-30 10:11:04 -04002867 for _, lib := range libs {
2868 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002869 cc_library {
2870 name: "%s",
2871 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002872 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002873 stl: "none",
2874 }
2875 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002876 }
2877
Colin Crossdd81e672024-10-17 14:01:12 -07002878 runTest := func(t *testing.T, variant string, expected []string) {
2879 ctx := android.GroupFixturePreparers(
2880 PrepareForIntegrationTestWithCc,
2881 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2882 ).RunTest(t)
2883 cflags := ctx.ModuleForTests("libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"]
Liz Kammer08572c62021-09-30 10:11:04 -04002884
Colin Crossdd81e672024-10-17 14:01:12 -07002885 var includes []string
2886 flags := strings.Split(cflags, " ")
2887 for _, flag := range flags {
2888 if strings.HasPrefix(flag, "-I") {
2889 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2890 } else if flag == "-isystem" {
2891 // skip isystem, include next
2892 } else if len(flag) > 0 {
2893 includes = append(includes, flag)
2894 }
Liz Kammer08572c62021-09-30 10:11:04 -04002895 }
Colin Crossdd81e672024-10-17 14:01:12 -07002896
2897 android.AssertArrayString(t, "includes", expected, includes)
Liz Kammer08572c62021-09-30 10:11:04 -04002898 }
2899
Colin Crossdd81e672024-10-17 14:01:12 -07002900 t.Run("platform", func(t *testing.T) {
2901 runTest(t, "android_arm_armv7-a-neon_static", tc.expectedPlatform)
2902 })
2903 t.Run("ndk", func(t *testing.T) {
2904 runTest(t, "android_arm_armv7-a-neon_sdk_static", tc.expectedNDK)
2905 })
Liz Kammer08572c62021-09-30 10:11:04 -04002906 })
Colin Crossae628182021-06-14 16:52:28 -07002907 }
2908
Colin Crossae628182021-06-14 16:52:28 -07002909}
Alixb5f6d9e2022-04-20 23:00:58 +00002910
zijunzhao933e3802023-01-12 07:26:20 +00002911func TestAddnoOverride64GlobalCflags(t *testing.T) {
2912 t.Parallel()
2913 ctx := testCc(t, `
2914 cc_library_shared {
2915 name: "libclient",
2916 srcs: ["foo.c"],
2917 shared_libs: ["libfoo#1"],
2918 }
2919
2920 cc_library_shared {
2921 name: "libfoo",
2922 srcs: ["foo.c"],
2923 shared_libs: ["libbar"],
2924 export_shared_lib_headers: ["libbar"],
2925 stubs: {
2926 symbol_file: "foo.map.txt",
2927 versions: ["1", "2", "3"],
2928 },
2929 }
2930
2931 cc_library_shared {
2932 name: "libbar",
2933 export_include_dirs: ["include/libbar"],
2934 srcs: ["foo.c"],
2935 }`)
2936
2937 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2938
2939 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2940 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2941 }
2942}
2943
Alixb5f6d9e2022-04-20 23:00:58 +00002944func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002945 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002946 tests := []struct {
2947 name string
2948 clang bool
2949 BuildBrokenClangProperty bool
2950 err string
2951 }{
2952 {
2953 name: "error when clang is set to false",
2954 clang: false,
2955 err: "is no longer supported",
2956 },
2957 {
2958 name: "error when clang is set to true",
2959 clang: true,
2960 err: "property is deprecated, see Changes.md",
2961 },
2962 {
2963 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2964 clang: true,
2965 BuildBrokenClangProperty: true,
2966 },
2967 }
2968
2969 for _, test := range tests {
2970 t.Run(test.name, func(t *testing.T) {
2971 bp := fmt.Sprintf(`
2972 cc_library {
2973 name: "foo",
2974 clang: %t,
2975 }`, test.clang)
2976
2977 if test.err == "" {
2978 android.GroupFixturePreparers(
2979 prepareForCcTest,
2980 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2981 if test.BuildBrokenClangProperty {
2982 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
2983 }
2984 }),
2985 ).RunTestWithBp(t, bp)
2986 } else {
2987 prepareForCcTest.
2988 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
2989 RunTestWithBp(t, bp)
2990 }
2991 })
2992 }
2993}
Alix Espinoef47e542022-09-14 19:10:51 +00002994
2995func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002996 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00002997 tests := []struct {
2998 name string
2999 clangAsFlags []string
3000 BuildBrokenClangAsFlags bool
3001 err string
3002 }{
3003 {
3004 name: "error when clang_asflags is set",
3005 clangAsFlags: []string{"-a", "-b"},
3006 err: "clang_asflags: property is deprecated",
3007 },
3008 {
3009 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3010 clangAsFlags: []string{"-a", "-b"},
3011 BuildBrokenClangAsFlags: true,
3012 },
3013 }
3014
3015 for _, test := range tests {
3016 t.Run(test.name, func(t *testing.T) {
3017 bp := fmt.Sprintf(`
3018 cc_library {
3019 name: "foo",
3020 clang_asflags: %s,
3021 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3022
3023 if test.err == "" {
3024 android.GroupFixturePreparers(
3025 prepareForCcTest,
3026 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3027 if test.BuildBrokenClangAsFlags {
3028 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3029 }
3030 }),
3031 ).RunTestWithBp(t, bp)
3032 } else {
3033 prepareForCcTest.
3034 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3035 RunTestWithBp(t, bp)
3036 }
3037 })
3038 }
3039}
3040
3041func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003042 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003043 tests := []struct {
3044 name string
3045 clangCFlags []string
3046 BuildBrokenClangCFlags bool
3047 err string
3048 }{
3049 {
3050 name: "error when clang_cflags is set",
3051 clangCFlags: []string{"-a", "-b"},
3052 err: "clang_cflags: property is deprecated",
3053 },
3054 {
3055 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3056 clangCFlags: []string{"-a", "-b"},
3057 BuildBrokenClangCFlags: true,
3058 },
3059 }
3060
3061 for _, test := range tests {
3062 t.Run(test.name, func(t *testing.T) {
3063 bp := fmt.Sprintf(`
3064 cc_library {
3065 name: "foo",
3066 clang_cflags: %s,
3067 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3068
3069 if test.err == "" {
3070 android.GroupFixturePreparers(
3071 prepareForCcTest,
3072 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3073 if test.BuildBrokenClangCFlags {
3074 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3075 }
3076 }),
3077 ).RunTestWithBp(t, bp)
3078 } else {
3079 prepareForCcTest.
3080 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3081 RunTestWithBp(t, bp)
3082 }
3083 })
3084 }
3085}
Wei Li5f5d2712023-12-11 15:40:29 -08003086
3087func TestStrippedAllOutputFile(t *testing.T) {
3088 t.Parallel()
3089 bp := `
3090 cc_library {
3091 name: "test_lib",
3092 srcs: ["test_lib.cpp"],
3093 dist: {
3094 targets: [ "dist_target" ],
3095 tag: "stripped_all",
3096 }
3097 }
3098 `
3099 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3100 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07003101 testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
Yu Liu51c22312024-08-20 23:56:15 +00003102 outputFile := testingModule.OutputFiles(ctx, t, "stripped_all")
Wei Li5f5d2712023-12-11 15:40:29 -08003103 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3104 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3105 return
3106 }
3107}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003108
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003109func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003110 t.Parallel()
3111
3112 bp := `
3113 cc_binary {
3114 name: "binfoo",
3115 srcs: ["binfoo.cc"],
3116 vendor_available: true,
3117 product_available: true,
3118 shared_libs: ["libbar"]
3119 }
3120 cc_library {
3121 name: "libbar",
3122 srcs: ["libbar.cc"],
3123 vendor_available: true,
3124 product_available: true,
3125 }
3126 `
3127
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003128 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003129
3130 hasDep := func(m android.Module, wantDep android.Module) bool {
3131 t.Helper()
3132 var found bool
3133 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3134 if dep == wantDep {
3135 found = true
3136 }
3137 })
3138 return found
3139 }
3140
3141 testDepWithVariant := func(imageVariant string) {
3142 imageVariantStr := ""
3143 if imageVariant != "core" {
3144 imageVariantStr = "_" + imageVariant
3145 }
3146 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3147 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3148 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3149 }
3150
3151 testDepWithVariant("core")
3152 testDepWithVariant("vendor")
3153 testDepWithVariant("product")
3154}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003155
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003156func TestVendorOrProductVariantUsesPlatformSdkVersionAsDefault(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003157 t.Parallel()
3158
3159 bp := `
3160 cc_library {
3161 name: "libfoo",
3162 srcs: ["libfoo.cc"],
3163 vendor_available: true,
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003164 product_available: true,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003165 }
3166
3167 cc_library {
3168 name: "libbar",
3169 srcs: ["libbar.cc"],
3170 vendor_available: true,
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003171 product_available: true,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003172 min_sdk_version: "29",
3173 }
3174 `
3175
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003176 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003177 testSdkVersionFlag := func(module, variant, version string) {
3178 flags := ctx.ModuleForTests(module, "android_"+variant+"_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3179 android.AssertStringDoesContain(t, "target SDK version", flags, "-target aarch64-linux-android"+version)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003180 }
3181
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003182 testSdkVersionFlag("libfoo", "vendor", "30")
3183 testSdkVersionFlag("libfoo", "product", "30")
3184 // target SDK version can be set explicitly with min_sdk_version
3185 testSdkVersionFlag("libbar", "vendor", "29")
3186 testSdkVersionFlag("libbar", "product", "29")
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003187}
kellyhungd62ea302024-05-19 21:16:07 +08003188
3189func TestClangVerify(t *testing.T) {
3190 t.Parallel()
3191
3192 ctx := testCc(t, `
3193 cc_library {
3194 name: "lib_no_clang_verify",
3195 srcs: ["libnocv.cc"],
3196 }
3197
3198 cc_library {
3199 name: "lib_clang_verify",
3200 srcs: ["libcv.cc"],
3201 clang_verify: true,
3202 }
3203 `)
3204
3205 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
3206
3207 cFlags_no_cv := module.Rule("cc").Args["cFlags"]
3208 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
3209 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
3210 }
3211
3212 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3213 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
3214 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
3215 }
3216}
Colin Cross516c5452024-10-28 13:45:21 -07003217
3218func TestCheckConflictingExplicitVersions(t *testing.T) {
3219 PrepareForIntegrationTestWithCc.
3220 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
3221 `shared_libs: duplicate shared libraries with different explicit versions: "libbar" and "libbar#impl"`,
3222 )).
3223 RunTestWithBp(t, `
3224 cc_library {
3225 name: "libfoo",
3226 shared_libs: ["libbar", "libbar#impl"],
3227 }
3228
3229 cc_library {
3230 name: "libbar",
3231 }
3232 `)
3233}