blob: 98af7b6551e3bda4cb672cda31ce69f7af803de2 [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,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090043)
44
Yu Liue4312402023-01-18 09:15:31 -080045var apexVariationName = "apex28"
46var apexVersion = "28"
47
48func registerTestMutators(ctx android.RegistrationContext) {
49 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -070050 ctx.Transition("apex", &testApexTransitionMutator{})
Yu Liue4312402023-01-18 09:15:31 -080051 })
52}
53
Colin Crossd27205e2024-09-12 22:41:37 -070054type testApexTransitionMutator struct{}
55
56func (t *testApexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
57 return []string{apexVariationName}
58}
59
60func (t *testApexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
61 return sourceVariation
62}
63
64func (t *testApexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
65 return incomingVariation
66}
67
68func (t *testApexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
Yu Liue4312402023-01-18 09:15:31 -080069 apexInfo := android.ApexInfo{
70 ApexVariationName: apexVariationName,
71 MinSdkVersion: android.ApiLevelForTest(apexVersion),
72 }
Colin Crossd27205e2024-09-12 22:41:37 -070073 android.SetProvider(ctx, android.ApexInfoProvider, apexInfo)
Yu Liue4312402023-01-18 09:15:31 -080074}
75
Paul Duffin8567f222021-03-23 00:02:06 +000076// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000077//
78// See testCc for an explanation as to how to stop using this deprecated method.
79//
80// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080081func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070082 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000083 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000084 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090085}
86
Paul Duffin8567f222021-03-23 00:02:06 +000087// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000088//
Paul Duffin8567f222021-03-23 00:02:06 +000089// 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 +000090// easier to customize the test behavior.
91//
92// 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 +000093// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000094// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
95// that it did not change the test behavior unexpectedly.
96//
97// deprecated
Logan Chienf3511742017-10-31 18:04:35 +080098func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080099 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +0000100 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +0000101 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +0800102}
103
Paul Duffin8567f222021-03-23 00:02:06 +0000104// testCcErrorWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000105//
106// See testCc for an explanation as to how to stop using this deprecated method.
107//
108// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900109func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800110 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800111
Paul Duffin8567f222021-03-23 00:02:06 +0000112 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000113 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
114 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800115}
116
Paul Duffin8567f222021-03-23 00:02:06 +0000117// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000118//
119// See testCc for an explanation as to how to stop using this deprecated method.
120//
121// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900122func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900123 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000124 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900125 testCcErrorWithConfig(t, pattern, config)
126 return
127}
128
Logan Chienf3511742017-10-31 18:04:35 +0800129const (
Colin Cross7113d202019-11-20 16:39:12 -0800130 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900131 vendorVariant = "android_vendor_arm64_armv8-a_shared"
132 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800133 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800134)
135
Paul Duffindb462dd2021-03-21 22:01:55 +0000136// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
137// running it in a fixture that requires all source files to exist.
138func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
139 android.GroupFixturePreparers(
140 PrepareForTestWithCcDefaultModules,
141 android.PrepareForTestDisallowNonExistentPaths,
142 ).RunTest(t)
143}
144
Jiyong Park6a43f042017-10-12 23:05:00 +0900145func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400146 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900147 ctx := testCc(t, `
148 cc_library {
149 name: "libTest",
150 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700151 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800152 nocrt: true,
153 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900154 vendor_available: true,
155 target: {
156 vendor: {
157 srcs: ["bar.c"],
158 },
159 },
160 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900161 `)
162
Logan Chienf3511742017-10-31 18:04:35 +0800163 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900164 var objs []string
165 for _, o := range ld.Inputs {
166 objs = append(objs, o.Base())
167 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800168 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900169 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
170 }
171}
172
Justin Yun7f99ec72021-04-12 13:19:28 +0900173func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
174 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
175 partitionDefined := false
176 checkPartition := func(specific bool, partition string) {
177 if specific {
178 if expected != partition && !partitionDefined {
179 // The variant is installed to the 'partition'
180 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
181 }
182 partitionDefined = true
183 } else {
184 // The variant is not installed to the 'partition'
185 if expected == partition {
186 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
187 }
188 }
189 }
190 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800191 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900192 }
193 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800194 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900195 }
196 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800197 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900198 }
199 systemExtSpecific := func(m *Module) bool {
200 return m.SystemExtSpecific()
201 }
202 checkPartition(socSpecific(mod), "vendor")
203 checkPartition(deviceSpecific(mod), "odm")
204 checkPartition(productSpecific(mod), "product")
205 checkPartition(systemExtSpecific(mod), "system_ext")
206 if !partitionDefined && expected != "system" {
207 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
208 " but installed to system partition", variant, name, expected)
209 }
210}
211
212func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400213 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900214 t.Helper()
215 ctx := prepareForCcTest.RunTestWithBp(t, `
216 cc_library {
217 name: "libsystem",
218 }
219 cc_library {
220 name: "libsystem_ext",
221 system_ext_specific: true,
222 }
223 cc_library {
224 name: "libproduct",
225 product_specific: true,
226 }
227 cc_library {
228 name: "libvendor",
229 vendor: true,
230 }
231 cc_library {
232 name: "libodm",
233 device_specific: true,
234 }
235 cc_library {
236 name: "liball_available",
237 vendor_available: true,
238 product_available: true,
239 }
240 cc_library {
241 name: "libsystem_ext_all_available",
242 system_ext_specific: true,
243 vendor_available: true,
244 product_available: true,
245 }
246 cc_library {
247 name: "liball_available_odm",
248 odm_available: true,
249 product_available: true,
250 }
251 cc_library {
252 name: "libproduct_vendoravailable",
253 product_specific: true,
254 vendor_available: true,
255 }
256 cc_library {
257 name: "libproduct_odmavailable",
258 product_specific: true,
259 odm_available: true,
260 }
261 `).TestContext
262
263 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
264 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
265 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
266 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
267 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
268
269 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
270 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
271 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
272
273 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
274 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
275 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
276
277 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
278 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
279 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
280
281 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
282 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
283
284 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
285 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
286}
287
Colin Crossf61d03d2023-11-02 16:56:39 -0700288func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900289 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700290 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800291 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900292 assertArrayString(t, actual, expected)
293}
294
Chris Parsons79d66a52020-06-05 17:26:16 -0400295func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400296 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400297 bp := `
298 cc_test_library {
299 name: "test_lib",
300 srcs: ["test_lib.cpp"],
301 gtest: false,
302 }
303
304 cc_test {
305 name: "main_test",
306 data_libs: ["test_lib"],
307 gtest: false,
308 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400309 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400310
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000311 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400312
313 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700314 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
315 testBinary := testingModule.Module().(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000316 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons79d66a52020-06-05 17:26:16 -0400317 if len(outputFiles) != 1 {
318 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
319 return
320 }
321 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800322 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400323 return
324 }
325
326 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400327 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400328
329 if !strings.HasSuffix(outputPath, "/main_test") {
330 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
331 return
332 }
333 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
334 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
335 return
336 }
337}
338
Chris Parsons216e10a2020-07-09 17:12:52 -0400339func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400340 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400341 bp := `
342 cc_test_library {
343 name: "test_lib",
344 srcs: ["test_lib.cpp"],
345 relative_install_path: "foo/bar/baz",
346 gtest: false,
347 }
348
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400349 cc_binary {
350 name: "test_bin",
351 relative_install_path: "foo/bar/baz",
352 compile_multilib: "both",
353 }
354
Chris Parsons216e10a2020-07-09 17:12:52 -0400355 cc_test {
356 name: "main_test",
357 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400358 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400359 gtest: false,
360 }
361 `
362
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000363 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400364
365 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700366 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
367 module := testingModule.Module()
Chris Parsons216e10a2020-07-09 17:12:52 -0400368 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +0000369 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons216e10a2020-07-09 17:12:52 -0400370 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400371 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400372 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400373 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800374 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400375 }
376
377 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400378
379 if !strings.HasSuffix(outputPath, "/main_test") {
380 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
381 }
Yu Liue70976d2024-10-15 20:45:35 +0000382 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Chris Parsons216e10a2020-07-09 17:12:52 -0400383 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
384 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400385 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400386 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400387 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
388 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
389 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
390 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400391}
392
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000393func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400394 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000395 bp := `
396 cc_test {
397 name: "main_test",
398 srcs: ["main_test.cpp"],
399 test_suites: [
400 "suite_1",
401 "suite_2",
402 ],
403 gtest: false,
404 }
405 `
406
407 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
408 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
409
Yu Liue70976d2024-10-15 20:45:35 +0000410 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000411 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
412 if len(compatEntries) != 2 {
413 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
414 }
415 if compatEntries[0] != "suite_1" {
416 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
417 " but was '%s'", compatEntries[0])
418 }
419 if compatEntries[1] != "suite_2" {
420 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
421 " but was '%s'", compatEntries[1])
422 }
423}
424
425func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400426 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000427 bp := `
428 cc_test_library {
429 name: "main_test_lib",
430 srcs: ["main_test_lib.cpp"],
431 test_suites: [
432 "suite_1",
433 "suite_2",
434 ],
435 gtest: false,
436 }
437 `
438
439 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
440 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
441
Yu Liue70976d2024-10-15 20:45:35 +0000442 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000443 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
444 if len(compatEntries) != 2 {
445 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
446 }
447 if compatEntries[0] != "suite_1" {
448 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
449 " but was '%s'", compatEntries[0])
450 }
451 if compatEntries[1] != "suite_2" {
452 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
453 " but was '%s'", compatEntries[1])
454 }
455}
456
Jooyung Hana70f0672019-01-18 15:20:43 +0900457func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400458 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900459 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900460 testCc(t, `
461 cc_library {
462 name: "libllndk",
463 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700464 llndk: {
465 symbol_file: "libllndk.map.txt",
466 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900467 }
468
469 cc_library {
470 name: "libdoubleloadable",
471 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900472 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900473 double_loadable: true,
474 }
475 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900476 // okay to link : double_loadable -> double_loadable
477 testCc(t, `
478 cc_library {
479 name: "libdoubleloadable1",
480 shared_libs: ["libdoubleloadable2"],
481 vendor_available: true,
482 double_loadable: true,
483 }
484
485 cc_library {
486 name: "libdoubleloadable2",
487 vendor_available: true,
488 double_loadable: true,
489 }
490 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900491 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900492 testCc(t, `
493 cc_library {
494 name: "libdoubleloadable",
495 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900496 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900497 double_loadable: true,
498 shared_libs: ["libnondoubleloadable"],
499 }
500
501 cc_library {
502 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900503 vendor_available: true,
504 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900505 double_loadable: true,
506 }
507 `)
508 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
509 testCc(t, `
510 cc_library {
511 name: "libllndk",
512 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700513 llndk: {
514 symbol_file: "libllndk.map.txt",
515 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900516 }
517
518 cc_library {
519 name: "libcoreonly",
520 shared_libs: ["libvendoravailable"],
521 }
522
523 // indirect dependency of LLNDK
524 cc_library {
525 name: "libvendoravailable",
526 vendor_available: true,
527 double_loadable: true,
528 }
529 `)
530}
531
532func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400533 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900534 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900535 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
536 cc_library {
537 name: "libllndk",
538 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700539 llndk: {
540 symbol_file: "libllndk.map.txt",
541 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900542 }
543
544 cc_library {
545 name: "libnondoubleloadable",
546 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900547 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900548 }
549 `)
550
551 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
552 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
553 cc_library {
554 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700555 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900556 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700557 llndk: {
558 symbol_file: "libllndk.map.txt",
559 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900560 }
561
562 cc_library {
563 name: "libnondoubleloadable",
564 vendor_available: true,
565 }
566 `)
567
Jooyung Hana70f0672019-01-18 15:20:43 +0900568 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
569 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
570 cc_library {
571 name: "libllndk",
572 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700573 llndk: {
574 symbol_file: "libllndk.map.txt",
575 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900576 }
577
578 cc_library {
579 name: "libcoreonly",
580 shared_libs: ["libvendoravailable"],
581 }
582
583 // indirect dependency of LLNDK
584 cc_library {
585 name: "libvendoravailable",
586 vendor_available: true,
587 }
588 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900589
590 // The error is not from 'client' but from 'libllndk'
591 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
592 cc_library {
593 name: "client",
594 vendor_available: true,
595 double_loadable: true,
596 shared_libs: ["libllndk"],
597 }
598 cc_library {
599 name: "libllndk",
600 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700601 llndk: {
602 symbol_file: "libllndk.map.txt",
603 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900604 }
605 cc_library {
606 name: "libnondoubleloadable",
607 vendor_available: true,
608 }
609 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800610}
611
Jooyung Han38002912019-05-16 04:01:54 +0900612func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400613 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800614 bp := `
615 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800616 name: "libvendor",
617 vendor: true,
618 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800619 vndk_prebuilt_shared {
620 name: "prevndk",
621 version: "27",
622 target_arch: "arm",
623 binder32bit: true,
624 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900625 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800626 vndk: {
627 enabled: true,
628 },
629 arch: {
630 arm: {
631 srcs: ["liba.so"],
632 },
633 },
634 }
635 cc_library {
636 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700637 llndk: {
638 symbol_file: "libllndk.map.txt",
639 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800640 }
641 cc_library {
642 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700643 llndk: {
644 symbol_file: "libllndkprivate.map.txt",
645 private: true,
646 }
Colin Cross78212242021-01-06 14:51:30 -0800647 }
Colin Cross78212242021-01-06 14:51:30 -0800648 llndk_libraries_txt {
649 name: "llndk.libraries.txt",
650 }
Colin Cross78212242021-01-06 14:51:30 -0800651 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800652
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000653 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900654 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800655 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900656
Colin Crossfb0c16e2019-11-20 17:12:35 -0800657 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900658
Jooyung Han38002912019-05-16 04:01:54 +0900659 tests := []struct {
660 variant string
661 name string
662 expected string
663 }{
Jooyung Han38002912019-05-16 04:01:54 +0900664 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800665 {vendorVariant, "libllndk", "native:vndk"},
Kiyoung Kim9f26fcf2024-05-27 17:25:52 +0900666 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +0900667 {coreVariant, "libllndk", "native:platform"},
668 }
669 for _, test := range tests {
670 t.Run(test.name, func(t *testing.T) {
671 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
672 assertString(t, module.makeLinkType, test.expected)
673 })
674 }
675}
676
Jeff Gaston294356f2017-09-27 17:05:30 -0700677var staticLinkDepOrderTestCases = []struct {
678 // This is a string representation of a map[moduleName][]moduleDependency .
679 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800680 inStatic string
681
682 // This is a string representation of a map[moduleName][]moduleDependency .
683 // It models the dependencies declared in an Android.bp file.
684 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700685
686 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
687 // The keys of allOrdered specify which modules we would like to check.
688 // The values of allOrdered specify the expected result (of the transitive closure of all
689 // dependencies) for each module to test
690 allOrdered string
691
692 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
693 // The keys of outOrdered specify which modules we would like to check.
694 // The values of outOrdered specify the expected result (of the ordered linker command line)
695 // for each module to test.
696 outOrdered string
697}{
698 // Simple tests
699 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800700 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700701 outOrdered: "",
702 },
703 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800704 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700705 outOrdered: "a:",
706 },
707 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800708 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700709 outOrdered: "a:b; b:",
710 },
711 // Tests of reordering
712 {
713 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800714 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700715 outOrdered: "a:b,c,d; b:d; c:d; d:",
716 },
717 {
718 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800719 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700720 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
721 },
722 {
723 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800724 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700725 outOrdered: "a:d,b,e,c; d:b; e:c",
726 },
727 {
728 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800729 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700730 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
731 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
732 },
733 {
734 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800735 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 -0700736 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
737 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
738 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800739 // shared dependencies
740 {
741 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
742 // So, we don't actually have to check that a shared dependency of c will change the order
743 // of a library that depends statically on b and on c. We only need to check that if c has
744 // a shared dependency on b, that that shows up in allOrdered.
745 inShared: "c:b",
746 allOrdered: "c:b",
747 outOrdered: "c:",
748 },
749 {
750 // This test doesn't actually include any shared dependencies but it's a reminder of what
751 // the second phase of the above test would look like
752 inStatic: "a:b,c; c:b",
753 allOrdered: "a:c,b; c:b",
754 outOrdered: "a:c,b; c:b",
755 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700756 // tiebreakers for when two modules specifying different orderings and there is no dependency
757 // to dictate an order
758 {
759 // 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 -0800760 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700761 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
762 },
763 {
764 // 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 -0800765 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 -0700766 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
767 },
768 // Tests involving duplicate dependencies
769 {
770 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800771 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700772 outOrdered: "a:c,b",
773 },
774 {
775 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800776 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700777 outOrdered: "a:d,c,b",
778 },
779 // Tests to confirm the nonexistence of infinite loops.
780 // These cases should never happen, so as long as the test terminates and the
781 // result is deterministic then that should be fine.
782 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800783 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700784 outOrdered: "a:a",
785 },
786 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800787 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700788 allOrdered: "a:b,c; b:c,a; c:a,b",
789 outOrdered: "a:b; b:c; c:a",
790 },
791 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800792 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700793 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
794 outOrdered: "a:c,b; b:a,c; c:b,a",
795 },
796}
797
798// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
799func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
800 // convert from "a:b,c; d:e" to "a:b,c;d:e"
801 strippedText := strings.Replace(text, " ", "", -1)
802 if len(strippedText) < 1 {
803 return []android.Path{}, make(map[android.Path][]android.Path, 0)
804 }
805 allDeps = make(map[android.Path][]android.Path, 0)
806
807 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
808 moduleTexts := strings.Split(strippedText, ";")
809
810 outputForModuleName := func(moduleName string) android.Path {
811 return android.PathForTesting(moduleName)
812 }
813
814 for _, moduleText := range moduleTexts {
815 // convert from "a:b,c" to ["a", "b,c"]
816 components := strings.Split(moduleText, ":")
817 if len(components) != 2 {
818 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
819 }
820 moduleName := components[0]
821 moduleOutput := outputForModuleName(moduleName)
822 modulesInOrder = append(modulesInOrder, moduleOutput)
823
824 depString := components[1]
825 // convert from "b,c" to ["b", "c"]
826 depNames := strings.Split(depString, ",")
827 if len(depString) < 1 {
828 depNames = []string{}
829 }
830 var deps []android.Path
831 for _, depName := range depNames {
832 deps = append(deps, outputForModuleName(depName))
833 }
834 allDeps[moduleOutput] = deps
835 }
836 return modulesInOrder, allDeps
837}
838
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800839func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400840 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700841 ctx := testCc(t, `
842 cc_library {
843 name: "a",
844 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900845 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700846 }
847 cc_library {
848 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900849 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700850 }
851 cc_library {
852 name: "c",
853 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900854 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700855 }
856 cc_library {
857 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900858 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700859 }
860
861 `)
862
Colin Cross7113d202019-11-20 16:39:12 -0800863 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700864 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000865 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800866 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400867 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700868
869 if !reflect.DeepEqual(actual, expected) {
870 t.Errorf("staticDeps orderings were not propagated correctly"+
871 "\nactual: %v"+
872 "\nexpected: %v",
873 actual,
874 expected,
875 )
876 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900877}
Jeff Gaston294356f2017-09-27 17:05:30 -0700878
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800879func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400880 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800881 ctx := testCc(t, `
882 cc_library {
883 name: "a",
884 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900885 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800886 }
887 cc_library {
888 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900889 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800890 }
891 cc_library {
892 name: "c",
893 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900894 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800895 }
896
897 `)
898
Colin Cross7113d202019-11-20 16:39:12 -0800899 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800900 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Yu Liu663e4502024-08-12 18:23:59 +0000901 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
Colin Cross5a377182023-12-14 14:46:23 -0800902 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400903 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800904
905 if !reflect.DeepEqual(actual, expected) {
906 t.Errorf("staticDeps orderings did not account for shared libs"+
907 "\nactual: %v"+
908 "\nexpected: %v",
909 actual,
910 expected,
911 )
912 }
913}
914
Jooyung Hanb04a4992020-03-13 18:57:35 +0900915func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700916 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900917 if !reflect.DeepEqual(actual, expected) {
918 t.Errorf(message+
919 "\nactual: %v"+
920 "\nexpected: %v",
921 actual,
922 expected,
923 )
924 }
925}
926
Jooyung Han61b66e92020-03-21 14:21:46 +0000927func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400928 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800929 result := prepareForCcTest.RunTestWithBp(t, `
930 cc_library {
931 name: "libllndk",
932 stubs: { versions: ["1", "2"] },
933 llndk: {
934 symbol_file: "libllndk.map.txt",
935 },
936 export_include_dirs: ["include"],
937 }
938
939 cc_prebuilt_library_shared {
940 name: "libllndkprebuilt",
Spandan Das357ffcc2024-07-24 18:07:48 +0000941 stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" },
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800942 llndk: {
943 symbol_file: "libllndkprebuilt.map.txt",
944 },
945 }
946
947 cc_library {
948 name: "libllndk_with_external_headers",
949 stubs: { versions: ["1", "2"] },
950 llndk: {
951 symbol_file: "libllndk.map.txt",
952 export_llndk_headers: ["libexternal_llndk_headers"],
953 },
954 header_libs: ["libexternal_headers"],
955 export_header_lib_headers: ["libexternal_headers"],
956 }
957 cc_library_headers {
958 name: "libexternal_headers",
959 export_include_dirs: ["include"],
960 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900961 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800962 }
963 cc_library_headers {
964 name: "libexternal_llndk_headers",
965 export_include_dirs: ["include_llndk"],
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800966 export_system_include_dirs: ["include_system_llndk"],
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800967 llndk: {
968 symbol_file: "libllndk.map.txt",
969 },
970 vendor_available: true,
971 }
972
973 cc_library {
974 name: "libllndk_with_override_headers",
975 stubs: { versions: ["1", "2"] },
976 llndk: {
977 symbol_file: "libllndk.map.txt",
978 override_export_include_dirs: ["include_llndk"],
979 },
980 export_include_dirs: ["include"],
981 }
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800982
983 cc_library {
984 name: "libllndk_with_system_headers",
985 llndk: {
986 symbol_file: "libllndk.map.txt",
987 export_llndk_headers: ["libexternal_llndk_headers"],
988 export_headers_as_system: true,
989 },
990 export_include_dirs: ["include"],
991 export_system_include_dirs: ["include_system"],
992 }
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800993 `)
994 actual := result.ModuleVariantsForTests("libllndk")
995 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900996 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800997 actual = append(actual[:i], actual[i+1:]...)
998 i--
999 }
1000 }
1001 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001002 "android_vendor_arm64_armv8-a_shared",
1003 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001004 }
1005 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
1006
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001007 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Justin Yun22abf212024-10-10 16:22:09 +09001008 android.AssertSame(t, "use Vendor API level for default stubs", "35", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001009
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001010 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001011 t.Helper()
1012 m := result.ModuleForTests(module, variant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001013 f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001014 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1015 expectedDirs, f.IncludeDirs)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001016 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1017 expectedSystemDirs, f.SystemIncludeDirs)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001018 }
1019
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001020 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
1021 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
1022 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
1023 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
1024 []string{"include_system_llndk"}, "include_llndk")
1025 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
1026 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
1027 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
1028 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
1029 []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001030
1031 checkAbiLinkerIncludeDirs := func(module string) {
1032 t.Helper()
1033 coreModule := result.ModuleForTests(module, coreVariant)
1034 abiCheckFlags := ""
1035 for _, output := range coreModule.AllOutputs() {
1036 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1037 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1038 }
1039 }
1040 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
Yu Liu663e4502024-08-12 18:23:59 +00001041 vendorInfo, _ := android.OtherModuleProvider(result, vendorModule, FlagExporterInfoProvider)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001042 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001043 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001044 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001045 }
1046 checkAbiLinkerIncludeDirs("libllndk")
1047 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1048 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001049 checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001050}
1051
Jiyong Parka46a4d52017-12-14 19:54:34 +09001052func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001053 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001054 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001055 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001056 name: "libllndk_headers",
1057 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001058 llndk: {
1059 llndk_headers: true,
1060 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001061 }
1062 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001063 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001064 llndk: {
1065 symbol_file: "libllndk.map.txt",
1066 export_llndk_headers: ["libllndk_headers"],
1067 }
Colin Cross0477b422020-10-13 18:43:54 -07001068 }
1069
1070 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001071 name: "libvendor",
1072 shared_libs: ["libllndk"],
1073 vendor: true,
1074 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001075 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001076 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001077 }
1078 `)
1079
1080 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001081 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001082 cflags := cc.Args["cFlags"]
1083 if !strings.Contains(cflags, "-Imy_include") {
1084 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1085 }
1086}
1087
Logan Chien43d34c32017-12-20 01:17:32 +08001088func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1089 actual := module.Properties.AndroidMkRuntimeLibs
1090 if !reflect.DeepEqual(actual, expected) {
1091 t.Errorf("incorrect runtime_libs for shared libs"+
1092 "\nactual: %v"+
1093 "\nexpected: %v",
1094 actual,
1095 expected,
1096 )
1097 }
1098}
1099
1100const runtimeLibAndroidBp = `
1101 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001102 name: "liball_available",
1103 vendor_available: true,
1104 product_available: true,
1105 no_libcrt : true,
1106 nocrt : true,
1107 system_shared_libs : [],
1108 }
1109 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001110 name: "libvendor_available1",
1111 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001112 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001113 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001114 nocrt : true,
1115 system_shared_libs : [],
1116 }
1117 cc_library {
1118 name: "libvendor_available2",
1119 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001120 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001121 target: {
1122 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001123 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001124 }
1125 },
Yi Konge7fe9912019-06-02 00:53:50 -07001126 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001127 nocrt : true,
1128 system_shared_libs : [],
1129 }
1130 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001131 name: "libproduct_vendor",
1132 product_specific: true,
1133 vendor_available: true,
1134 no_libcrt : true,
1135 nocrt : true,
1136 system_shared_libs : [],
1137 }
1138 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001139 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001140 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001141 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001142 nocrt : true,
1143 system_shared_libs : [],
1144 }
1145 cc_library {
1146 name: "libvendor1",
1147 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001148 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001149 nocrt : true,
1150 system_shared_libs : [],
1151 }
1152 cc_library {
1153 name: "libvendor2",
1154 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001155 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001156 no_libcrt : true,
1157 nocrt : true,
1158 system_shared_libs : [],
1159 }
1160 cc_library {
1161 name: "libproduct_available1",
1162 product_available: true,
1163 runtime_libs: ["liball_available"],
1164 no_libcrt : true,
1165 nocrt : true,
1166 system_shared_libs : [],
1167 }
1168 cc_library {
1169 name: "libproduct1",
1170 product_specific: true,
1171 no_libcrt : true,
1172 nocrt : true,
1173 system_shared_libs : [],
1174 }
1175 cc_library {
1176 name: "libproduct2",
1177 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001178 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001179 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001180 nocrt : true,
1181 system_shared_libs : [],
1182 }
1183`
1184
1185func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001186 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001187 ctx := testCc(t, runtimeLibAndroidBp)
1188
1189 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001190 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001191
Justin Yun8a2600c2020-12-07 12:44:03 +09001192 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1193 checkRuntimeLibs(t, []string{"liball_available"}, module)
1194
1195 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1196 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001197
1198 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001199 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001200
1201 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1202 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001203 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001204
Justin Yun8a2600c2020-12-07 12:44:03 +09001205 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1206 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001207
1208 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001209 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001210
1211 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1212 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001213 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001214
1215 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1216 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1217
1218 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001219 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001220}
1221
1222func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001223 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001224 ctx := testCc(t, runtimeLibAndroidBp)
1225
Colin Cross7113d202019-11-20 16:39:12 -08001226 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001227 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1228 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001229
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001230 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001231 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001232 checkRuntimeLibs(t, nil, module)
1233}
1234
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001235func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001236 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001237 actual := module.Properties.AndroidMkStaticLibs
1238 if !reflect.DeepEqual(actual, expected) {
1239 t.Errorf("incorrect static_libs"+
1240 "\nactual: %v"+
1241 "\nexpected: %v",
1242 actual,
1243 expected,
1244 )
1245 }
1246}
1247
1248const staticLibAndroidBp = `
1249 cc_library {
1250 name: "lib1",
1251 }
1252 cc_library {
1253 name: "lib2",
1254 static_libs: ["lib1"],
1255 }
1256`
1257
1258func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001259 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001260 ctx := testCc(t, staticLibAndroidBp)
1261
1262 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001263 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001264 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001265 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001266
1267 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001268 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001269 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1270 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001271 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001272}
1273
Jiyong Parkd08b6972017-09-26 10:50:54 +09001274var compilerFlagsTestCases = []struct {
1275 in string
1276 out bool
1277}{
1278 {
1279 in: "a",
1280 out: false,
1281 },
1282 {
1283 in: "-a",
1284 out: true,
1285 },
1286 {
1287 in: "-Ipath/to/something",
1288 out: false,
1289 },
1290 {
1291 in: "-isystempath/to/something",
1292 out: false,
1293 },
1294 {
1295 in: "--coverage",
1296 out: false,
1297 },
1298 {
1299 in: "-include a/b",
1300 out: true,
1301 },
1302 {
1303 in: "-include a/b c/d",
1304 out: false,
1305 },
1306 {
1307 in: "-DMACRO",
1308 out: true,
1309 },
1310 {
1311 in: "-DMAC RO",
1312 out: false,
1313 },
1314 {
1315 in: "-a -b",
1316 out: false,
1317 },
1318 {
1319 in: "-DMACRO=definition",
1320 out: true,
1321 },
1322 {
1323 in: "-DMACRO=defi nition",
1324 out: true, // TODO(jiyong): this should be false
1325 },
1326 {
1327 in: "-DMACRO(x)=x + 1",
1328 out: true,
1329 },
1330 {
1331 in: "-DMACRO=\"defi nition\"",
1332 out: true,
1333 },
1334}
1335
1336type mockContext struct {
1337 BaseModuleContext
1338 result bool
1339}
1340
1341func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1342 // CheckBadCompilerFlags calls this function when the flag should be rejected
1343 ctx.result = false
1344}
1345
1346func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001347 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001348 for _, testCase := range compilerFlagsTestCases {
1349 ctx := &mockContext{result: true}
1350 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1351 if ctx.result != testCase.out {
1352 t.Errorf("incorrect output:")
1353 t.Errorf(" input: %#v", testCase.in)
1354 t.Errorf(" expected: %#v", testCase.out)
1355 t.Errorf(" got: %#v", ctx.result)
1356 }
1357 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001358}
Jiyong Park374510b2018-03-19 18:23:01 +09001359
Jiyong Park37b25202018-07-11 10:49:27 +09001360func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001361 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001362 ctx := testCc(t, `
1363 cc_library_shared {
1364 name: "librecovery",
1365 recovery: true,
1366 }
1367 cc_library_shared {
1368 name: "librecovery32",
1369 recovery: true,
1370 compile_multilib:"32",
1371 }
Jiyong Park5baac542018-08-28 09:55:37 +09001372 cc_library_shared {
1373 name: "libHalInRecovery",
1374 recovery_available: true,
1375 vendor: true,
1376 }
Jiyong Park37b25202018-07-11 10:49:27 +09001377 `)
1378
1379 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001380 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001381 if len(variants) != 1 || !android.InList(arm64, variants) {
1382 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1383 }
1384
1385 variants = ctx.ModuleVariantsForTests("librecovery32")
1386 if android.InList(arm64, variants) {
1387 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1388 }
Jiyong Park5baac542018-08-28 09:55:37 +09001389
1390 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1391 if !recoveryModule.Platform() {
1392 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1393 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001394}
Jiyong Park5baac542018-08-28 09:55:37 +09001395
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001396func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001397 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001398 bp := `
1399 cc_prebuilt_test_library_shared {
1400 name: "test_lib",
1401 relative_install_path: "foo/bar/baz",
1402 srcs: ["srcpath/dontusethispath/baz.so"],
1403 }
1404
1405 cc_test {
1406 name: "main_test",
1407 data_libs: ["test_lib"],
1408 gtest: false,
1409 }
1410 `
1411
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001412 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001413
1414 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07001415 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
1416 module := testingModule.Module()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001417 testBinary := module.(*Module).linker.(*testBinary)
Yu Liu51c22312024-08-20 23:56:15 +00001418 outputFiles := testingModule.OutputFiles(ctx, t, "")
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001419 if len(outputFiles) != 1 {
1420 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1421 }
1422 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001423 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001424 }
1425
1426 outputPath := outputFiles[0].String()
1427
1428 if !strings.HasSuffix(outputPath, "/main_test") {
1429 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1430 }
Yu Liue70976d2024-10-15 20:45:35 +00001431 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001432 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1433 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1434 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1435 }
1436}
1437
Jiyong Park7ed9de32018-10-15 22:25:07 +09001438func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001439 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001440 ctx := testCc(t, `
1441 cc_library_shared {
1442 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001443 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001444 stubs: {
1445 symbol_file: "foo.map.txt",
1446 versions: ["1", "2", "3"],
1447 },
1448 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001449
Jiyong Park7ed9de32018-10-15 22:25:07 +09001450 cc_library_shared {
1451 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001452 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001453 shared_libs: ["libFoo#1"],
1454 }`)
1455
1456 variants := ctx.ModuleVariantsForTests("libFoo")
1457 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001458 "android_arm64_armv8-a_shared",
1459 "android_arm64_armv8-a_shared_1",
1460 "android_arm64_armv8-a_shared_2",
1461 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001462 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001463 "android_arm_armv7-a-neon_shared",
1464 "android_arm_armv7-a-neon_shared_1",
1465 "android_arm_armv7-a-neon_shared_2",
1466 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001467 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001468 }
1469 variantsMismatch := false
1470 if len(variants) != len(expectedVariants) {
1471 variantsMismatch = true
1472 } else {
1473 for _, v := range expectedVariants {
1474 if !inList(v, variants) {
1475 variantsMismatch = false
1476 }
1477 }
1478 }
1479 if variantsMismatch {
1480 t.Errorf("variants of libFoo expected:\n")
1481 for _, v := range expectedVariants {
1482 t.Errorf("%q\n", v)
1483 }
1484 t.Errorf(", but got:\n")
1485 for _, v := range variants {
1486 t.Errorf("%q\n", v)
1487 }
1488 }
1489
Colin Cross7113d202019-11-20 16:39:12 -08001490 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001491 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001492 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001493 if !strings.Contains(libFlags, libFoo1StubPath) {
1494 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1495 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001496
Colin Cross7113d202019-11-20 16:39:12 -08001497 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001498 cFlags := libBarCompileRule.Args["cFlags"]
1499 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1500 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1501 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1502 }
Jiyong Park37b25202018-07-11 10:49:27 +09001503}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001504
Jooyung Hanb04a4992020-03-13 18:57:35 +09001505func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001506 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001507 for _, tc := range []struct{ moduleName, expected string }{
1508 {"libc", "__LIBC_API__"},
1509 {"libfoo", "__LIBFOO_API__"},
1510 {"libfoo@1", "__LIBFOO_1_API__"},
1511 {"libfoo-v1", "__LIBFOO_V1_API__"},
1512 {"libfoo.v1", "__LIBFOO_V1_API__"},
1513 } {
1514 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1515 }
1516}
1517
Liz Kammer83cf81b2022-09-22 08:24:20 -04001518func pathsToBase(paths android.Paths) []string {
1519 var ret []string
1520 for _, p := range paths {
1521 ret = append(ret, p.Base())
1522 }
1523 return ret
1524}
1525
1526func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001527 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001528 ctx := testCc(t, `
1529 cc_library_static {
1530 name: "foo",
1531 srcs: ["foo.c"],
1532 }
1533
1534 cc_library_static {
1535 name: "bar",
1536 srcs: ["bar.c"],
1537 }
1538
1539 cc_library_shared {
1540 name: "qux",
1541 srcs: ["qux.c"],
1542 }
1543
1544 cc_library_static {
1545 name: "baz",
1546 srcs: ["baz.c"],
1547 static_libs: ["foo"],
1548 shared_libs: ["qux"],
1549 whole_static_libs: ["bar"],
1550 }`)
1551
1552 variant := "android_arm64_armv8-a_static"
1553 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1554
1555 // For static libraries, the object files of a whole static dep are included in the archive
1556 // directly
1557 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1558 t.Errorf("Expected input objects %q, got %q", w, g)
1559 }
1560
1561 // non whole static dependencies are not linked into the archive
1562 if len(arRule.Implicits) > 0 {
1563 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1564 }
1565}
1566
1567func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001568 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001569 ctx := testCc(t, `
1570 cc_library_static {
1571 name: "foo",
1572 srcs: ["foo.c"],
1573 }
1574
1575 cc_library_static {
1576 name: "bar",
1577 srcs: ["bar.c"],
1578 }
1579
1580 cc_library_shared {
1581 name: "qux",
1582 srcs: ["qux.c"],
1583 }
1584
1585 cc_library_shared {
1586 name: "baz",
1587 srcs: ["baz.c"],
1588 static_libs: ["foo"],
1589 shared_libs: ["qux"],
1590 whole_static_libs: ["bar"],
1591 }`)
1592
1593 variant := "android_arm64_armv8-a_shared"
1594 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1595 libFlags := linkRule.Args["libFlags"]
1596 // When dynamically linking, we expect static dependencies to be found on the command line
1597 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1598 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1599 }
1600 // When dynamically linking, we expect whole static dependencies to be found on the command line
1601 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1602 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1603 }
1604
1605 // When dynamically linking, we expect shared dependencies to be found on the command line
1606 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1607 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1608 }
1609
1610 // We should only have the objects from the shared library srcs, not the whole static dependencies
1611 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1612 t.Errorf("Expected input objects %q, got %q", w, g)
1613 }
1614}
1615
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001616func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001617 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001618 ctx := testCc(t, `
1619 cc_binary {
1620 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001621 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001622 static_executable: true,
1623 }`)
1624
Colin Cross7113d202019-11-20 16:39:12 -08001625 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001626 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1627 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001628 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001629 for _, lib := range systemStaticLibs {
1630 if !strings.Contains(libFlags, lib) {
1631 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1632 }
1633 }
1634 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1635 for _, lib := range systemSharedLibs {
1636 if strings.Contains(libFlags, lib) {
1637 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1638 }
1639 }
1640}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001641
1642func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001643 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001644 ctx := testCc(t, `
1645 cc_binary {
1646 name: "mybin",
1647 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001648 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001649 static_executable: true,
1650 stl: "none",
1651 }
1652
1653 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001654 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001655 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001656 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001657 stl: "none",
1658 }
1659
1660 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001661 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001662 srcs: ["foo.c"],
1663 stl: "none",
1664 stubs: {
1665 versions: ["1"],
1666 },
1667 }`)
1668
Colin Cross0de8a1e2020-09-18 14:15:30 -07001669 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1670 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001671 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001672
1673 if !reflect.DeepEqual(actual, expected) {
1674 t.Errorf("staticDeps orderings were not propagated correctly"+
1675 "\nactual: %v"+
1676 "\nexpected: %v",
1677 actual,
1678 expected,
1679 )
1680 }
1681}
Jooyung Han38002912019-05-16 04:01:54 +09001682
Jooyung Hand48f3c32019-08-23 11:18:57 +09001683func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001684 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001685 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1686 cc_library {
1687 name: "libA",
1688 srcs: ["foo.c"],
1689 shared_libs: ["libB"],
1690 stl: "none",
1691 }
1692
1693 cc_library {
1694 name: "libB",
1695 srcs: ["foo.c"],
1696 enabled: false,
1697 stl: "none",
1698 }
1699 `)
1700}
1701
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001702func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1703 bp := `
1704 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001705 name: "test_afl_fuzz_target",
1706 srcs: ["foo.c"],
1707 host_supported: true,
1708 static_libs: [
1709 "afl_fuzz_static_lib",
1710 ],
1711 shared_libs: [
1712 "afl_fuzz_shared_lib",
1713 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001714 fuzzing_frameworks: {
1715 afl: true,
1716 libfuzzer: false,
1717 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001718 }
1719 cc_library {
1720 name: "afl_fuzz_static_lib",
1721 host_supported: true,
1722 srcs: ["static_file.c"],
1723 }
1724 cc_library {
1725 name: "libfuzzer_only_static_lib",
1726 host_supported: true,
1727 srcs: ["static_file.c"],
1728 }
1729 cc_library {
1730 name: "afl_fuzz_shared_lib",
1731 host_supported: true,
1732 srcs: ["shared_file.c"],
1733 static_libs: [
1734 "second_static_lib",
1735 ],
1736 }
1737 cc_library_headers {
1738 name: "libafl_headers",
1739 vendor_available: true,
1740 host_supported: true,
1741 export_include_dirs: [
1742 "include",
1743 "instrumentation",
1744 ],
1745 }
1746 cc_object {
1747 name: "afl-compiler-rt",
1748 vendor_available: true,
1749 host_supported: true,
1750 cflags: [
1751 "-fPIC",
1752 ],
1753 srcs: [
1754 "instrumentation/afl-compiler-rt.o.c",
1755 ],
1756 }
1757 cc_library {
1758 name: "second_static_lib",
1759 host_supported: true,
1760 srcs: ["second_file.c"],
1761 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001762 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001763 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001764 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001765 srcs: [
1766 "aflpp_driver.c",
1767 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001768 }`
1769
1770 testEnv := map[string]string{
1771 "FUZZ_FRAMEWORK": "AFL",
1772 }
1773
1774 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001775
1776 checkPcGuardFlag := func(
1777 modName string, variantName string, shouldHave bool) {
1778 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1779
1780 cFlags, ok := cc.Args["cFlags"]
1781 if !ok {
1782 t.Errorf("Could not find cFlags for module %s and variant %s",
1783 modName, variantName)
1784 }
1785
1786 if strings.Contains(
1787 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1788 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1789 "Test failed for module %s and variant %s",
1790 !shouldHave, shouldHave, modName, variantName)
1791 }
1792 }
1793
Cory Barkera1da26f2022-06-07 20:12:06 +00001794 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001795 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001796
1797 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001798 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001799 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001800
1801 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001802 checkPcGuardFlag(moduleName, variant+"_static", false)
Colin Cross597bad62024-10-08 15:10:55 -07001803 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001804
1805 ctx.ModuleForTests("afl_fuzz_shared_lib",
1806 "android_arm64_armv8-a_shared").Rule("cc")
1807 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001808 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1809}
1810
1811func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001812 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001813 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1814}
1815
1816func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001817 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001818 if runtime.GOOS != "linux" {
1819 t.Skip("requires linux")
1820 }
1821
1822 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001823}
1824
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001825// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1826// correctly.
1827func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001828 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001829 ctx := testCc(t, `
1830 cc_fuzz {
1831 name: "fuzz_smoke_test",
1832 srcs: ["foo.c"],
1833 }`)
1834
Paul Duffin075c4172019-12-19 19:06:13 +00001835 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001836 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1837}
1838
Jooyung Han38002912019-05-16 04:01:54 +09001839func assertString(t *testing.T, got, expected string) {
1840 t.Helper()
1841 if got != expected {
1842 t.Errorf("expected %q got %q", expected, got)
1843 }
1844}
1845
1846func assertArrayString(t *testing.T, got, expected []string) {
1847 t.Helper()
1848 if len(got) != len(expected) {
1849 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1850 return
1851 }
1852 for i := range got {
1853 if got[i] != expected[i] {
1854 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1855 i, expected[i], expected, got[i], got)
1856 return
1857 }
1858 }
1859}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001860
Jooyung Han0302a842019-10-30 18:43:49 +09001861func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1862 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001863 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001864}
1865
Colin Crosse1bb5d02019-09-24 14:55:04 -07001866func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001867 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001868 ctx := testCc(t, `
1869 cc_defaults {
1870 name: "defaults",
1871 srcs: ["foo.c"],
1872 static: {
1873 srcs: ["bar.c"],
1874 },
1875 shared: {
1876 srcs: ["baz.c"],
1877 },
1878 }
1879
1880 cc_library_static {
1881 name: "libstatic",
1882 defaults: ["defaults"],
1883 }
1884
1885 cc_library_shared {
1886 name: "libshared",
1887 defaults: ["defaults"],
1888 }
1889
1890 cc_library {
1891 name: "libboth",
1892 defaults: ["defaults"],
1893 }
1894
1895 cc_binary {
1896 name: "binary",
1897 defaults: ["defaults"],
1898 }`)
1899
Colin Cross7113d202019-11-20 16:39:12 -08001900 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001901 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1902 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
1903 }
Colin Cross7113d202019-11-20 16:39:12 -08001904 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001905 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1906 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
1907 }
Colin Cross7113d202019-11-20 16:39:12 -08001908 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001909 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
1910 t.Errorf("binary ld rule wanted %q, got %q", w, g)
1911 }
1912
Colin Cross7113d202019-11-20 16:39:12 -08001913 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001914 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1915 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
1916 }
Colin Cross7113d202019-11-20 16:39:12 -08001917 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001918 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1919 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
1920 }
1921}
Colin Crosseabaedd2020-02-06 17:01:55 -08001922
1923func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001924 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08001925 bp := `
1926 cc_defaults {
1927 name: "libfoo_defaults",
1928 srcs: ["foo.c"],
1929 cppflags: ["-DFOO"],
1930 product_variables: {
1931 debuggable: {
1932 cppflags: ["-DBAR"],
1933 },
1934 },
1935 }
1936
1937 cc_library {
1938 name: "libfoo",
1939 defaults: ["libfoo_defaults"],
1940 }
1941 `
1942
Paul Duffin8567f222021-03-23 00:02:06 +00001943 result := android.GroupFixturePreparers(
1944 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001945 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08001946
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001947 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1948 variables.Debuggable = BoolPtr(true)
1949 }),
1950 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08001951
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001952 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00001953 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08001954}
Colin Crosse4f6eba2020-09-22 18:11:25 -07001955
1956func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
1957 t.Parallel()
1958 bp := `
1959 cc_library_static {
1960 name: "libfoo",
1961 srcs: ["foo.c"],
1962 whole_static_libs: ["libbar"],
1963 }
1964
1965 cc_library_static {
1966 name: "libbar",
1967 whole_static_libs: ["libmissing"],
1968 }
1969 `
1970
Paul Duffin8567f222021-03-23 00:02:06 +00001971 result := android.GroupFixturePreparers(
1972 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001973 android.PrepareForTestWithAllowMissingDependencies,
1974 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07001975
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001976 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00001977 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07001978
Paul Duffine84b1332021-03-12 11:59:43 +00001979 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07001980
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00001981 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00001982 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07001983}
Colin Crosse9fe2942020-11-10 18:12:15 -08001984
1985func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001986 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08001987 bp := `
1988 cc_binary {
1989 name: "bin",
1990 host_supported: true,
1991 shared_libs: ["libshared"],
1992 runtime_libs: ["libruntime"],
1993 srcs: [":gen"],
1994 }
1995
1996 cc_library_shared {
1997 name: "libshared",
1998 host_supported: true,
1999 shared_libs: ["libtransitive"],
2000 }
2001
2002 cc_library_shared {
2003 name: "libtransitive",
2004 host_supported: true,
2005 }
2006
2007 cc_library_shared {
2008 name: "libruntime",
2009 host_supported: true,
2010 }
2011
2012 cc_binary_host {
2013 name: "tool",
2014 srcs: ["foo.cpp"],
2015 }
2016
2017 genrule {
2018 name: "gen",
2019 tools: ["tool"],
2020 out: ["gen.cpp"],
2021 cmd: "$(location tool) $(out)",
2022 }
2023 `
2024
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002025 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002026 ctx := testCcWithConfig(t, config)
2027
2028 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2029 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2030 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2031 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2032 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2033
2034 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2035 t.Errorf("expected host bin dependency %q, got %q", w, g)
2036 }
2037
2038 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2039 t.Errorf("expected host bin dependency %q, got %q", w, g)
2040 }
2041
2042 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2043 t.Errorf("expected host bin dependency %q, got %q", w, g)
2044 }
2045
2046 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2047 t.Errorf("expected host bin dependency %q, got %q", w, g)
2048 }
2049
2050 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2051 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2052 }
2053
2054 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2055 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2056 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2057 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2058
2059 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2060 t.Errorf("expected device bin dependency %q, got %q", w, g)
2061 }
2062
2063 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2064 t.Errorf("expected device bin dependency %q, got %q", w, g)
2065 }
2066
2067 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2068 t.Errorf("expected device bin dependency %q, got %q", w, g)
2069 }
2070
2071 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2072 t.Errorf("expected device bin dependency %q, got %q", w, g)
2073 }
2074
2075 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2076 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2077 }
2078
2079}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002080
2081func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002082 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002083 ctx := testCc(t, `
2084 cc_library_shared {
2085 name: "libclient",
2086 srcs: ["foo.c"],
2087 shared_libs: ["libfoo#1"],
2088 }
2089
2090 cc_library_shared {
2091 name: "libfoo",
2092 srcs: ["foo.c"],
2093 shared_libs: ["libbar"],
2094 export_shared_lib_headers: ["libbar"],
2095 stubs: {
2096 symbol_file: "foo.map.txt",
2097 versions: ["1", "2", "3"],
2098 },
2099 }
2100
2101 cc_library_shared {
2102 name: "libbar",
2103 export_include_dirs: ["include/libbar"],
2104 srcs: ["foo.c"],
2105 }`)
2106
2107 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2108
2109 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2110 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2111 }
2112}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002113
Vinh Tran09581952023-05-16 16:03:20 -04002114func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002115 t.Parallel()
2116 ctx := android.GroupFixturePreparers(
2117 prepareForCcTest,
2118 aidl_library.PrepareForTestWithAidlLibrary,
2119 android.MockFS{
2120 "package_bar/Android.bp": []byte(`
2121 aidl_library {
2122 name: "bar",
2123 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002124 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002125 strip_import_prefix: "x",
2126 }
2127 `)}.AddToFixture(),
2128 android.MockFS{
2129 "package_foo/Android.bp": []byte(`
2130 aidl_library {
2131 name: "foo",
2132 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002133 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002134 strip_import_prefix: "a",
2135 deps: ["bar"],
2136 }
2137 cc_library {
2138 name: "libfoo",
2139 aidl: {
2140 libs: ["foo"],
2141 }
2142 }
2143 `),
2144 }.AddToFixture(),
2145 ).RunTest(t).TestContext
2146
2147 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002148
2149 android.AssertPathsRelativeToTopEquals(
2150 t,
2151 "aidl headers",
2152 []string{
2153 "package_bar/x/HeaderBar.aidl",
2154 "package_foo/a/HeaderFoo.aidl",
2155 "package_foo/a/b/Foo.aidl",
2156 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2157 },
2158 libfoo.Rule("aidl_library").Implicits,
2159 )
2160
Colin Crossf61d03d2023-11-02 16:56:39 -07002161 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002162 aidlCommand := manifest.Commands[0].GetCommand()
2163
2164 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2165 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2166 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2167 }
2168
2169 outputs := strings.Join(libfoo.AllOutputs(), " ")
2170
Vinh Tran09581952023-05-16 16:03:20 -04002171 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2172 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2173 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002174 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2175 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002176 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2177 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2178 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002179 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2180}
2181
Jooyung Hane197d8b2021-01-05 10:33:16 +09002182func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002183 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002184 ctx := android.GroupFixturePreparers(
2185 prepareForCcTest,
2186 aidl_library.PrepareForTestWithAidlLibrary,
2187 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002188 cc_library {
2189 name: "libfoo",
2190 srcs: ["a/Foo.aidl"],
2191 aidl: { flags: ["-Werror"], },
2192 }
2193 `)
2194
2195 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002196 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002197 aidlCommand := manifest.Commands[0].GetCommand()
2198 expectedAidlFlag := "-Werror"
2199 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2200 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2201 }
2202}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002203
Jooyung Han07f70c02021-11-06 07:08:45 +09002204func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002205 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002206 for _, tc := range []struct {
2207 name string
2208 sdkVersion string
2209 variant string
2210 expected string
2211 }{
2212 {
2213 name: "default is current",
2214 sdkVersion: "",
2215 variant: "android_arm64_armv8-a_static",
2216 expected: "platform_apis",
2217 },
2218 {
2219 name: "use sdk_version",
2220 sdkVersion: `sdk_version: "29"`,
2221 variant: "android_arm64_armv8-a_static",
2222 expected: "platform_apis",
2223 },
2224 {
2225 name: "use sdk_version(sdk variant)",
2226 sdkVersion: `sdk_version: "29"`,
2227 variant: "android_arm64_armv8-a_sdk_static",
2228 expected: "29",
2229 },
2230 {
2231 name: "use min_sdk_version",
2232 sdkVersion: `min_sdk_version: "29"`,
2233 variant: "android_arm64_armv8-a_static",
2234 expected: "29",
2235 },
2236 } {
2237 t.Run(tc.name, func(t *testing.T) {
2238 ctx := testCc(t, `
2239 cc_library {
2240 name: "libfoo",
2241 stl: "none",
2242 srcs: ["a/Foo.aidl"],
2243 `+tc.sdkVersion+`
2244 }
2245 `)
2246 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002247 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002248 aidlCommand := manifest.Commands[0].GetCommand()
2249 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2250 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2251 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2252 }
2253 })
2254 }
2255}
2256
Vinh Tran09581952023-05-16 16:03:20 -04002257func TestInvalidAidlProp(t *testing.T) {
2258 t.Parallel()
2259
2260 testCases := []struct {
2261 description string
2262 bp string
2263 }{
2264 {
2265 description: "Invalid use of aidl.libs and aidl.include_dirs",
2266 bp: `
2267 cc_library {
2268 name: "foo",
2269 aidl: {
2270 libs: ["foo_aidl"],
2271 include_dirs: ["bar/include"],
2272 }
2273 }
2274 `,
2275 },
2276 {
2277 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2278 bp: `
2279 cc_library {
2280 name: "foo",
2281 aidl: {
2282 libs: ["foo_aidl"],
2283 local_include_dirs: ["include"],
2284 }
2285 }
2286 `,
2287 },
2288 }
2289
2290 for _, testCase := range testCases {
2291 t.Run(testCase.description, func(t *testing.T) {
2292 bp := `
2293 aidl_library {
2294 name: "foo_aidl",
2295 srcs: ["Foo.aidl"],
2296 } ` + testCase.bp
2297 android.GroupFixturePreparers(
2298 prepareForCcTest,
2299 aidl_library.PrepareForTestWithAidlLibrary.
2300 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2301 ).RunTestWithBp(t, bp)
2302 })
2303 }
2304}
2305
Jiyong Parka008fb02021-03-16 17:15:53 +09002306func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002307 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002308 ctx := testCc(t, `
2309 cc_library_shared {
2310 name: "libfoo",
2311 srcs: ["foo.c"],
2312 min_sdk_version: "29",
2313 }`)
2314
2315 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2316 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2317}
2318
Vinh Tranf1924742022-06-24 16:40:11 -04002319func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002320 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002321 bp := `
2322 cc_library_shared {
2323 name: "libfoo",
2324 srcs: ["foo.c"],
2325 min_sdk_version: "S",
2326 }
2327 `
2328 result := android.GroupFixturePreparers(
2329 prepareForCcTest,
2330 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2331 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2332 }),
2333 ).RunTestWithBp(t, bp)
2334 ctx := result.TestContext
2335 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2336 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2337}
2338
Paul Duffin3cb603e2021-02-19 13:57:10 +00002339func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002340 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002341
2342 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2343 // embedded newline characters alone.
2344 trimIndentingSpaces := func(s string) string {
2345 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2346 }
2347
2348 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2349 t.Helper()
2350 expected = trimIndentingSpaces(expected)
2351 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2352 if expected != actual {
2353 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2354 }
2355 }
2356
2357 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2358
2359 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2360 t.Helper()
Yu Liu663e4502024-08-12 18:23:59 +00002361 exported, _ := android.OtherModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002362 name := module.Name()
2363
2364 for _, checker := range checkers {
2365 checker(t, name, exported)
2366 }
2367 }
2368
2369 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2370 return func(t *testing.T, name string, exported FlagExporterInfo) {
2371 t.Helper()
2372 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2373 }
2374 }
2375
2376 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2377 return func(t *testing.T, name string, exported FlagExporterInfo) {
2378 t.Helper()
2379 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2380 }
2381 }
2382
2383 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2384 return func(t *testing.T, name string, exported FlagExporterInfo) {
2385 t.Helper()
2386 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2387 }
2388 }
2389
2390 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2391 return func(t *testing.T, name string, exported FlagExporterInfo) {
2392 t.Helper()
2393 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2394 }
2395 }
2396
2397 genRuleModules := `
2398 genrule {
2399 name: "genrule_foo",
2400 cmd: "generate-foo",
2401 out: [
2402 "generated_headers/foo/generated_header.h",
2403 ],
2404 export_include_dirs: [
2405 "generated_headers",
2406 ],
2407 }
2408
2409 genrule {
2410 name: "genrule_bar",
2411 cmd: "generate-bar",
2412 out: [
2413 "generated_headers/bar/generated_header.h",
2414 ],
2415 export_include_dirs: [
2416 "generated_headers",
2417 ],
2418 }
2419 `
2420
2421 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2422 ctx := testCc(t, genRuleModules+`
2423 cc_library {
2424 name: "libfoo",
2425 srcs: ["foo.c"],
2426 export_include_dirs: ["foo/standard"],
2427 export_system_include_dirs: ["foo/system"],
2428 generated_headers: ["genrule_foo"],
2429 export_generated_headers: ["genrule_foo"],
2430 }
2431
2432 cc_library {
2433 name: "libbar",
2434 srcs: ["bar.c"],
2435 shared_libs: ["libfoo"],
2436 export_include_dirs: ["bar/standard"],
2437 export_system_include_dirs: ["bar/system"],
2438 generated_headers: ["genrule_bar"],
2439 export_generated_headers: ["genrule_bar"],
2440 }
2441 `)
2442 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2443 checkIncludeDirs(t, ctx, foo,
2444 expectedIncludeDirs(`
2445 foo/standard
2446 .intermediates/genrule_foo/gen/generated_headers
2447 `),
2448 expectedSystemIncludeDirs(`foo/system`),
2449 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2450 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2451 )
2452
2453 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2454 checkIncludeDirs(t, ctx, bar,
2455 expectedIncludeDirs(`
2456 bar/standard
2457 .intermediates/genrule_bar/gen/generated_headers
2458 `),
2459 expectedSystemIncludeDirs(`bar/system`),
2460 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2461 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2462 )
2463 })
2464
2465 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2466 ctx := testCc(t, genRuleModules+`
2467 cc_library {
2468 name: "libfoo",
2469 srcs: ["foo.c"],
2470 export_include_dirs: ["foo/standard"],
2471 export_system_include_dirs: ["foo/system"],
2472 generated_headers: ["genrule_foo"],
2473 export_generated_headers: ["genrule_foo"],
2474 }
2475
2476 cc_library {
2477 name: "libbar",
2478 srcs: ["bar.c"],
2479 whole_static_libs: ["libfoo"],
2480 export_include_dirs: ["bar/standard"],
2481 export_system_include_dirs: ["bar/system"],
2482 generated_headers: ["genrule_bar"],
2483 export_generated_headers: ["genrule_bar"],
2484 }
2485 `)
2486 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2487 checkIncludeDirs(t, ctx, foo,
2488 expectedIncludeDirs(`
2489 foo/standard
2490 .intermediates/genrule_foo/gen/generated_headers
2491 `),
2492 expectedSystemIncludeDirs(`foo/system`),
2493 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2494 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2495 )
2496
2497 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2498 checkIncludeDirs(t, ctx, bar,
2499 expectedIncludeDirs(`
2500 bar/standard
2501 foo/standard
2502 .intermediates/genrule_foo/gen/generated_headers
2503 .intermediates/genrule_bar/gen/generated_headers
2504 `),
2505 expectedSystemIncludeDirs(`
2506 bar/system
2507 foo/system
2508 `),
2509 expectedGeneratedHeaders(`
2510 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2511 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2512 `),
2513 expectedOrderOnlyDeps(`
2514 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2515 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2516 `),
2517 )
2518 })
2519
Paul Duffin3cb603e2021-02-19 13:57:10 +00002520 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002521 ctx := android.GroupFixturePreparers(
2522 prepareForCcTest,
2523 aidl_library.PrepareForTestWithAidlLibrary,
2524 ).RunTestWithBp(t, `
2525 aidl_library {
2526 name: "libfoo_aidl",
2527 srcs: ["x/y/Bar.aidl"],
2528 strip_import_prefix: "x",
2529 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002530 cc_library_shared {
2531 name: "libfoo",
2532 srcs: [
2533 "foo.c",
2534 "b.aidl",
2535 "a.proto",
2536 ],
2537 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002538 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002539 export_aidl_headers: true,
2540 }
2541 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002542 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002543 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2544 checkIncludeDirs(t, ctx, foo,
2545 expectedIncludeDirs(`
2546 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002547 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002548 `),
2549 expectedSystemIncludeDirs(``),
2550 expectedGeneratedHeaders(`
2551 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2552 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2553 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002554 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2555 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2556 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002557 `),
2558 expectedOrderOnlyDeps(`
2559 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2560 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2561 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002562 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2563 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2564 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002565 `),
2566 )
2567 })
2568
Paul Duffin3cb603e2021-02-19 13:57:10 +00002569 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2570 ctx := testCc(t, genRuleModules+`
2571 cc_library_shared {
2572 name: "libfoo",
2573 srcs: [
2574 "foo.c",
2575 "b.aidl",
2576 "a.proto",
2577 ],
2578 proto: {
2579 export_proto_headers: true,
2580 }
2581 }
2582 `)
2583 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2584 checkIncludeDirs(t, ctx, foo,
2585 expectedIncludeDirs(`
2586 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2587 `),
2588 expectedSystemIncludeDirs(``),
2589 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002590 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2591 `),
2592 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002593 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2594 `),
2595 )
2596 })
2597
Paul Duffin33056e82021-02-19 13:49:08 +00002598 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002599 ctx := testCc(t, genRuleModules+`
2600 cc_library_shared {
2601 name: "libfoo",
2602 srcs: [
2603 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002604 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002605 "b.aidl",
2606 "a.proto",
2607 ],
2608 }
2609 `)
2610 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2611 checkIncludeDirs(t, ctx, foo,
2612 expectedIncludeDirs(`
2613 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2614 `),
2615 expectedSystemIncludeDirs(``),
2616 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002617 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002618 `),
2619 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002620 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2621 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002622 `),
2623 )
2624 })
2625}
Colin Crossae628182021-06-14 16:52:28 -07002626
2627func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002628 t.Parallel()
Colin Cross0e097dd2024-10-17 11:41:28 -07002629
2630 expectedPlatformFlags := []string{
2631 "-nostdlibinc",
2632 }
2633
Liz Kammer08572c62021-09-30 10:11:04 -04002634 baseExpectedFlags := []string{
2635 "${config.ArmThumbCflags}",
2636 "${config.ArmCflags}",
2637 "${config.CommonGlobalCflags}",
2638 "${config.DeviceGlobalCflags}",
2639 "${config.ExternalCflags}",
2640 "${config.ArmToolchainCflags}",
2641 "${config.ArmArmv7ANeonCflags}",
2642 "${config.ArmGenericCflags}",
Colin Crossdd81e672024-10-17 14:01:12 -07002643 }
2644
2645 expectedTargetNDKFlags := []string{
Liz Kammer08572c62021-09-30 10:11:04 -04002646 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002647 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002648 }
2649
Colin Crossdd81e672024-10-17 14:01:12 -07002650 expectedTargetPlatformFlags := []string{
2651 "-target",
2652 "armv7a-linux-androideabi10000",
2653 }
2654
Liz Kammer08572c62021-09-30 10:11:04 -04002655 expectedIncludes := []string{
2656 "external/foo/android_arm_export_include_dirs",
2657 "external/foo/lib32_export_include_dirs",
2658 "external/foo/arm_export_include_dirs",
2659 "external/foo/android_export_include_dirs",
2660 "external/foo/linux_export_include_dirs",
2661 "external/foo/export_include_dirs",
2662 "external/foo/android_arm_local_include_dirs",
2663 "external/foo/lib32_local_include_dirs",
2664 "external/foo/arm_local_include_dirs",
2665 "external/foo/android_local_include_dirs",
2666 "external/foo/linux_local_include_dirs",
2667 "external/foo/local_include_dirs",
2668 "external/foo",
2669 "external/foo/libheader1",
2670 "external/foo/libheader2",
2671 "external/foo/libwhole1",
2672 "external/foo/libwhole2",
2673 "external/foo/libstatic1",
2674 "external/foo/libstatic2",
2675 "external/foo/libshared1",
2676 "external/foo/libshared2",
2677 "external/foo/liblinux",
2678 "external/foo/libandroid",
2679 "external/foo/libarm",
2680 "external/foo/lib32",
2681 "external/foo/libandroid_arm",
Colin Crossdd81e672024-10-17 14:01:12 -07002682 }
2683
2684 expectedNDKSTLIncludes := []string{
Ryan Prichard2a69eb62024-07-30 01:58:54 +00002685 "defaults/cc/common/ndk_libc++_shared_include_dirs",
Liz Kammer08572c62021-09-30 10:11:04 -04002686 }
2687
2688 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2689 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2690
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002691 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002692 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002693 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002694
Colin Cross0e097dd2024-10-17 11:41:28 -07002695 lastNDKFlags := []string{
2696 "--sysroot",
2697 "out/soong/ndk/sysroot",
Liz Kammer08572c62021-09-30 10:11:04 -04002698 }
2699
Colin Crossdd81e672024-10-17 14:01:12 -07002700 lastPlatformIncludes := []string{
2701 "${config.CommonGlobalIncludes}",
Liz Kammer08572c62021-09-30 10:11:04 -04002702 }
2703
2704 testCases := []struct {
Colin Crossdd81e672024-10-17 14:01:12 -07002705 name string
2706 src string
2707 expectedNDK []string
2708 expectedPlatform []string
Liz Kammer08572c62021-09-30 10:11:04 -04002709 }{
2710 {
Colin Crossdd81e672024-10-17 14:01:12 -07002711 name: "c",
2712 src: "foo.c",
2713 expectedNDK: slices.Concat(
2714 baseExpectedFlags,
2715 expectedTargetNDKFlags,
2716 conly,
2717 expectedIncludes,
2718 expectedNDKSTLIncludes,
2719 cflags,
2720 cstd,
Colin Cross0e097dd2024-10-17 11:41:28 -07002721 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002722 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2723 ),
2724 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002725 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002726 baseExpectedFlags,
2727 expectedTargetPlatformFlags,
2728 conly,
2729 expectedIncludes,
2730 cflags,
2731 cstd,
2732 lastPlatformIncludes,
2733 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2734 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002735 },
2736 {
Colin Crossdd81e672024-10-17 14:01:12 -07002737 name: "cc",
2738 src: "foo.cc",
2739 expectedNDK: slices.Concat(
2740 baseExpectedFlags,
2741 expectedTargetNDKFlags,
2742 cppOnly,
2743 expectedIncludes,
2744 expectedNDKSTLIncludes,
2745 cflags,
2746 cppstd,
Colin Cross0e097dd2024-10-17 11:41:28 -07002747 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002748 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2749 ),
2750 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002751 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002752 baseExpectedFlags,
2753 expectedTargetPlatformFlags,
2754 cppOnly,
2755 expectedIncludes,
2756 cflags,
2757 cppstd,
2758 lastPlatformIncludes,
2759 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
2760 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002761 },
2762 {
Colin Crossdd81e672024-10-17 14:01:12 -07002763 name: "assemble",
2764 src: "foo.s",
2765 expectedNDK: slices.Concat(
2766 baseExpectedFlags,
2767 expectedTargetNDKFlags,
2768 []string{"${config.CommonGlobalAsflags}"},
2769 expectedIncludes,
2770 expectedNDKSTLIncludes,
Colin Cross0e097dd2024-10-17 11:41:28 -07002771 lastNDKFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002772 ),
2773 expectedPlatform: slices.Concat(
Colin Cross0e097dd2024-10-17 11:41:28 -07002774 expectedPlatformFlags,
Colin Crossdd81e672024-10-17 14:01:12 -07002775 baseExpectedFlags,
2776 expectedTargetPlatformFlags,
2777 []string{"${config.CommonGlobalAsflags}"},
2778 expectedIncludes,
2779 lastPlatformIncludes,
2780 ),
Liz Kammer08572c62021-09-30 10:11:04 -04002781 },
2782 }
2783
2784 for _, tc := range testCases {
2785 t.Run(tc.name, func(t *testing.T) {
2786 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002787 cc_library {
2788 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002789 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002790 cflags: ["-std=candcpp"],
2791 conlyflags: ["-std=conly"],
2792 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002793 local_include_dirs: ["local_include_dirs"],
2794 export_include_dirs: ["export_include_dirs"],
2795 export_system_include_dirs: ["export_system_include_dirs"],
2796 static_libs: ["libstatic1", "libstatic2"],
2797 whole_static_libs: ["libwhole1", "libwhole2"],
2798 shared_libs: ["libshared1", "libshared2"],
2799 header_libs: ["libheader1", "libheader2"],
2800 target: {
2801 android: {
2802 shared_libs: ["libandroid"],
2803 local_include_dirs: ["android_local_include_dirs"],
2804 export_include_dirs: ["android_export_include_dirs"],
2805 },
2806 android_arm: {
2807 shared_libs: ["libandroid_arm"],
2808 local_include_dirs: ["android_arm_local_include_dirs"],
2809 export_include_dirs: ["android_arm_export_include_dirs"],
2810 },
2811 linux: {
2812 shared_libs: ["liblinux"],
2813 local_include_dirs: ["linux_local_include_dirs"],
2814 export_include_dirs: ["linux_export_include_dirs"],
2815 },
2816 },
2817 multilib: {
2818 lib32: {
2819 shared_libs: ["lib32"],
2820 local_include_dirs: ["lib32_local_include_dirs"],
2821 export_include_dirs: ["lib32_export_include_dirs"],
2822 },
2823 },
2824 arch: {
2825 arm: {
2826 shared_libs: ["libarm"],
2827 local_include_dirs: ["arm_local_include_dirs"],
2828 export_include_dirs: ["arm_export_include_dirs"],
2829 },
2830 },
2831 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002832 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002833 }
2834
2835 cc_library_headers {
2836 name: "libheader1",
2837 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002838 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002839 stl: "none",
2840 }
2841
2842 cc_library_headers {
2843 name: "libheader2",
2844 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002845 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002846 stl: "none",
2847 }
Liz Kammer08572c62021-09-30 10:11:04 -04002848 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002849
Liz Kammer08572c62021-09-30 10:11:04 -04002850 libs := []string{
2851 "libstatic1",
2852 "libstatic2",
2853 "libwhole1",
2854 "libwhole2",
2855 "libshared1",
2856 "libshared2",
2857 "libandroid",
2858 "libandroid_arm",
2859 "liblinux",
2860 "lib32",
2861 "libarm",
2862 }
Colin Crossae628182021-06-14 16:52:28 -07002863
Liz Kammer08572c62021-09-30 10:11:04 -04002864 for _, lib := range libs {
2865 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002866 cc_library {
2867 name: "%s",
2868 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002869 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002870 stl: "none",
2871 }
2872 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002873 }
2874
Colin Crossdd81e672024-10-17 14:01:12 -07002875 runTest := func(t *testing.T, variant string, expected []string) {
2876 ctx := android.GroupFixturePreparers(
2877 PrepareForIntegrationTestWithCc,
2878 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2879 ).RunTest(t)
2880 cflags := ctx.ModuleForTests("libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"]
Liz Kammer08572c62021-09-30 10:11:04 -04002881
Colin Crossdd81e672024-10-17 14:01:12 -07002882 var includes []string
2883 flags := strings.Split(cflags, " ")
2884 for _, flag := range flags {
2885 if strings.HasPrefix(flag, "-I") {
2886 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2887 } else if flag == "-isystem" {
2888 // skip isystem, include next
2889 } else if len(flag) > 0 {
2890 includes = append(includes, flag)
2891 }
Liz Kammer08572c62021-09-30 10:11:04 -04002892 }
Colin Crossdd81e672024-10-17 14:01:12 -07002893
2894 android.AssertArrayString(t, "includes", expected, includes)
Liz Kammer08572c62021-09-30 10:11:04 -04002895 }
2896
Colin Crossdd81e672024-10-17 14:01:12 -07002897 t.Run("platform", func(t *testing.T) {
2898 runTest(t, "android_arm_armv7-a-neon_static", tc.expectedPlatform)
2899 })
2900 t.Run("ndk", func(t *testing.T) {
2901 runTest(t, "android_arm_armv7-a-neon_sdk_static", tc.expectedNDK)
2902 })
Liz Kammer08572c62021-09-30 10:11:04 -04002903 })
Colin Crossae628182021-06-14 16:52:28 -07002904 }
2905
Colin Crossae628182021-06-14 16:52:28 -07002906}
Alixb5f6d9e2022-04-20 23:00:58 +00002907
zijunzhao933e3802023-01-12 07:26:20 +00002908func TestAddnoOverride64GlobalCflags(t *testing.T) {
2909 t.Parallel()
2910 ctx := testCc(t, `
2911 cc_library_shared {
2912 name: "libclient",
2913 srcs: ["foo.c"],
2914 shared_libs: ["libfoo#1"],
2915 }
2916
2917 cc_library_shared {
2918 name: "libfoo",
2919 srcs: ["foo.c"],
2920 shared_libs: ["libbar"],
2921 export_shared_lib_headers: ["libbar"],
2922 stubs: {
2923 symbol_file: "foo.map.txt",
2924 versions: ["1", "2", "3"],
2925 },
2926 }
2927
2928 cc_library_shared {
2929 name: "libbar",
2930 export_include_dirs: ["include/libbar"],
2931 srcs: ["foo.c"],
2932 }`)
2933
2934 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2935
2936 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2937 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2938 }
2939}
2940
Alixb5f6d9e2022-04-20 23:00:58 +00002941func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002942 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002943 tests := []struct {
2944 name string
2945 clang bool
2946 BuildBrokenClangProperty bool
2947 err string
2948 }{
2949 {
2950 name: "error when clang is set to false",
2951 clang: false,
2952 err: "is no longer supported",
2953 },
2954 {
2955 name: "error when clang is set to true",
2956 clang: true,
2957 err: "property is deprecated, see Changes.md",
2958 },
2959 {
2960 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2961 clang: true,
2962 BuildBrokenClangProperty: true,
2963 },
2964 }
2965
2966 for _, test := range tests {
2967 t.Run(test.name, func(t *testing.T) {
2968 bp := fmt.Sprintf(`
2969 cc_library {
2970 name: "foo",
2971 clang: %t,
2972 }`, test.clang)
2973
2974 if test.err == "" {
2975 android.GroupFixturePreparers(
2976 prepareForCcTest,
2977 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2978 if test.BuildBrokenClangProperty {
2979 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
2980 }
2981 }),
2982 ).RunTestWithBp(t, bp)
2983 } else {
2984 prepareForCcTest.
2985 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
2986 RunTestWithBp(t, bp)
2987 }
2988 })
2989 }
2990}
Alix Espinoef47e542022-09-14 19:10:51 +00002991
2992func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002993 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00002994 tests := []struct {
2995 name string
2996 clangAsFlags []string
2997 BuildBrokenClangAsFlags bool
2998 err string
2999 }{
3000 {
3001 name: "error when clang_asflags is set",
3002 clangAsFlags: []string{"-a", "-b"},
3003 err: "clang_asflags: property is deprecated",
3004 },
3005 {
3006 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3007 clangAsFlags: []string{"-a", "-b"},
3008 BuildBrokenClangAsFlags: true,
3009 },
3010 }
3011
3012 for _, test := range tests {
3013 t.Run(test.name, func(t *testing.T) {
3014 bp := fmt.Sprintf(`
3015 cc_library {
3016 name: "foo",
3017 clang_asflags: %s,
3018 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3019
3020 if test.err == "" {
3021 android.GroupFixturePreparers(
3022 prepareForCcTest,
3023 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3024 if test.BuildBrokenClangAsFlags {
3025 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3026 }
3027 }),
3028 ).RunTestWithBp(t, bp)
3029 } else {
3030 prepareForCcTest.
3031 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3032 RunTestWithBp(t, bp)
3033 }
3034 })
3035 }
3036}
3037
3038func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003039 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003040 tests := []struct {
3041 name string
3042 clangCFlags []string
3043 BuildBrokenClangCFlags bool
3044 err string
3045 }{
3046 {
3047 name: "error when clang_cflags is set",
3048 clangCFlags: []string{"-a", "-b"},
3049 err: "clang_cflags: property is deprecated",
3050 },
3051 {
3052 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3053 clangCFlags: []string{"-a", "-b"},
3054 BuildBrokenClangCFlags: true,
3055 },
3056 }
3057
3058 for _, test := range tests {
3059 t.Run(test.name, func(t *testing.T) {
3060 bp := fmt.Sprintf(`
3061 cc_library {
3062 name: "foo",
3063 clang_cflags: %s,
3064 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3065
3066 if test.err == "" {
3067 android.GroupFixturePreparers(
3068 prepareForCcTest,
3069 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3070 if test.BuildBrokenClangCFlags {
3071 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3072 }
3073 }),
3074 ).RunTestWithBp(t, bp)
3075 } else {
3076 prepareForCcTest.
3077 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3078 RunTestWithBp(t, bp)
3079 }
3080 })
3081 }
3082}
Wei Li5f5d2712023-12-11 15:40:29 -08003083
3084func TestStrippedAllOutputFile(t *testing.T) {
3085 t.Parallel()
3086 bp := `
3087 cc_library {
3088 name: "test_lib",
3089 srcs: ["test_lib.cpp"],
3090 dist: {
3091 targets: [ "dist_target" ],
3092 tag: "stripped_all",
3093 }
3094 }
3095 `
3096 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3097 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07003098 testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
Yu Liu51c22312024-08-20 23:56:15 +00003099 outputFile := testingModule.OutputFiles(ctx, t, "stripped_all")
Wei Li5f5d2712023-12-11 15:40:29 -08003100 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3101 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3102 return
3103 }
3104}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003105
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003106func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003107 t.Parallel()
3108
3109 bp := `
3110 cc_binary {
3111 name: "binfoo",
3112 srcs: ["binfoo.cc"],
3113 vendor_available: true,
3114 product_available: true,
3115 shared_libs: ["libbar"]
3116 }
3117 cc_library {
3118 name: "libbar",
3119 srcs: ["libbar.cc"],
3120 vendor_available: true,
3121 product_available: true,
3122 }
3123 `
3124
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003125 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003126
3127 hasDep := func(m android.Module, wantDep android.Module) bool {
3128 t.Helper()
3129 var found bool
3130 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3131 if dep == wantDep {
3132 found = true
3133 }
3134 })
3135 return found
3136 }
3137
3138 testDepWithVariant := func(imageVariant string) {
3139 imageVariantStr := ""
3140 if imageVariant != "core" {
3141 imageVariantStr = "_" + imageVariant
3142 }
3143 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3144 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3145 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3146 }
3147
3148 testDepWithVariant("core")
3149 testDepWithVariant("vendor")
3150 testDepWithVariant("product")
3151}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003152
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003153func TestVendorOrProductVariantUsesPlatformSdkVersionAsDefault(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003154 t.Parallel()
3155
3156 bp := `
3157 cc_library {
3158 name: "libfoo",
3159 srcs: ["libfoo.cc"],
3160 vendor_available: true,
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003161 product_available: true,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003162 }
3163
3164 cc_library {
3165 name: "libbar",
3166 srcs: ["libbar.cc"],
3167 vendor_available: true,
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003168 product_available: true,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003169 min_sdk_version: "29",
3170 }
3171 `
3172
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003173 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003174 testSdkVersionFlag := func(module, variant, version string) {
3175 flags := ctx.ModuleForTests(module, "android_"+variant+"_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3176 android.AssertStringDoesContain(t, "target SDK version", flags, "-target aarch64-linux-android"+version)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003177 }
3178
Jooyung Hanaa2d3f52024-11-09 02:41:06 +00003179 testSdkVersionFlag("libfoo", "vendor", "30")
3180 testSdkVersionFlag("libfoo", "product", "30")
3181 // target SDK version can be set explicitly with min_sdk_version
3182 testSdkVersionFlag("libbar", "vendor", "29")
3183 testSdkVersionFlag("libbar", "product", "29")
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003184}
kellyhungd62ea302024-05-19 21:16:07 +08003185
3186func TestClangVerify(t *testing.T) {
3187 t.Parallel()
3188
3189 ctx := testCc(t, `
3190 cc_library {
3191 name: "lib_no_clang_verify",
3192 srcs: ["libnocv.cc"],
3193 }
3194
3195 cc_library {
3196 name: "lib_clang_verify",
3197 srcs: ["libcv.cc"],
3198 clang_verify: true,
3199 }
3200 `)
3201
3202 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
3203
3204 cFlags_no_cv := module.Rule("cc").Args["cFlags"]
3205 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
3206 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
3207 }
3208
3209 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3210 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
3211 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
3212 }
3213}
Colin Cross516c5452024-10-28 13:45:21 -07003214
3215func TestCheckConflictingExplicitVersions(t *testing.T) {
3216 PrepareForIntegrationTestWithCc.
3217 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
3218 `shared_libs: duplicate shared libraries with different explicit versions: "libbar" and "libbar#impl"`,
3219 )).
3220 RunTestWithBp(t, `
3221 cc_library {
3222 name: "libfoo",
3223 shared_libs: ["libbar", "libbar#impl"],
3224 }
3225
3226 cc_library {
3227 name: "libbar",
3228 }
3229 `)
3230}