blob: ccdaae58f21d24b1244a7b228b396250d19ebcfc [file] [log] [blame]
Colin Crossd00350c2017-11-17 10:55:38 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross74d1ec02015-04-28 13:30:13 -070015package cc
16
17import (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "os"
Colin Cross74d1ec02015-04-28 13:30:13 -070020 "reflect"
Paul Duffin3cb603e2021-02-19 13:57:10 +000021 "regexp"
Cory Barker9cfcf6d2022-07-22 17:22:02 +000022 "runtime"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070025
Vinh Tran367d89d2023-04-28 11:21:25 -040026 "android/soong/aidl_library"
Colin Crosse1bb5d02019-09-24 14:55:04 -070027 "android/soong/android"
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090028
29 "github.com/google/blueprint"
Colin Cross74d1ec02015-04-28 13:30:13 -070030)
31
Yu Liue4312402023-01-18 09:15:31 -080032func init() {
33 registerTestMutators(android.InitRegistrationContext)
34}
35
Jiyong Park6a43f042017-10-12 23:05:00 +090036func TestMain(m *testing.M) {
Paul Duffinc3e6ce02021-03-22 23:21:32 +000037 os.Exit(m.Run())
Jiyong Park6a43f042017-10-12 23:05:00 +090038}
39
Paul Duffin2e6f90e2021-03-22 23:20:25 +000040var prepareForCcTest = android.GroupFixturePreparers(
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090041 PrepareForIntegrationTestWithCc,
42 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
43 variables.VendorApiLevel = StringPtr("202404")
44 }),
45)
46
Yu Liue4312402023-01-18 09:15:31 -080047var apexVariationName = "apex28"
48var apexVersion = "28"
49
50func registerTestMutators(ctx android.RegistrationContext) {
51 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
52 ctx.BottomUp("apex", testApexMutator).Parallel()
Yu Liue4312402023-01-18 09:15:31 -080053 })
54}
55
Yu Liue4312402023-01-18 09:15:31 -080056func testApexMutator(mctx android.BottomUpMutatorContext) {
57 modules := mctx.CreateVariations(apexVariationName)
58 apexInfo := android.ApexInfo{
59 ApexVariationName: apexVariationName,
60 MinSdkVersion: android.ApiLevelForTest(apexVersion),
61 }
62 mctx.SetVariationProvider(modules[0], android.ApexInfoProvider, apexInfo)
63}
64
Paul Duffin8567f222021-03-23 00:02:06 +000065// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000066//
67// See testCc for an explanation as to how to stop using this deprecated method.
68//
69// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080070func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070071 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000072 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000073 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090074}
75
Paul Duffin8567f222021-03-23 00:02:06 +000076// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000077//
Paul Duffin8567f222021-03-23 00:02:06 +000078// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
Paul Duffin02a3d652021-02-24 18:51:54 +000079// easier to customize the test behavior.
80//
81// If it is necessary to customize the behavior of an existing test that uses this then please first
Paul Duffin8567f222021-03-23 00:02:06 +000082// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000083// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
84// that it did not change the test behavior unexpectedly.
85//
86// deprecated
Logan Chienf3511742017-10-31 18:04:35 +080087func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080088 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000089 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +000090 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +080091}
92
Paul Duffin8567f222021-03-23 00:02:06 +000093// testCcErrorWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000094//
95// See testCc for an explanation as to how to stop using this deprecated method.
96//
97// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +090098func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +080099 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800100
Paul Duffin8567f222021-03-23 00:02:06 +0000101 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000102 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
103 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800104}
105
Paul Duffin8567f222021-03-23 00:02:06 +0000106// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000107//
108// See testCc for an explanation as to how to stop using this deprecated method.
109//
110// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900111func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900112 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000113 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900114 testCcErrorWithConfig(t, pattern, config)
115 return
116}
117
Logan Chienf3511742017-10-31 18:04:35 +0800118const (
Colin Cross7113d202019-11-20 16:39:12 -0800119 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900120 vendorVariant = "android_vendor_arm64_armv8-a_shared"
121 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800122 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800123)
124
Paul Duffindb462dd2021-03-21 22:01:55 +0000125// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
126// running it in a fixture that requires all source files to exist.
127func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
128 android.GroupFixturePreparers(
129 PrepareForTestWithCcDefaultModules,
130 android.PrepareForTestDisallowNonExistentPaths,
131 ).RunTest(t)
132}
133
Jiyong Park6a43f042017-10-12 23:05:00 +0900134func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400135 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900136 ctx := testCc(t, `
137 cc_library {
138 name: "libTest",
139 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700140 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800141 nocrt: true,
142 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900143 vendor_available: true,
144 target: {
145 vendor: {
146 srcs: ["bar.c"],
147 },
148 },
149 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900150 `)
151
Logan Chienf3511742017-10-31 18:04:35 +0800152 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900153 var objs []string
154 for _, o := range ld.Inputs {
155 objs = append(objs, o.Base())
156 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800157 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900158 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
159 }
160}
161
Justin Yun7f99ec72021-04-12 13:19:28 +0900162func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
163 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
164 partitionDefined := false
165 checkPartition := func(specific bool, partition string) {
166 if specific {
167 if expected != partition && !partitionDefined {
168 // The variant is installed to the 'partition'
169 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
170 }
171 partitionDefined = true
172 } else {
173 // The variant is not installed to the 'partition'
174 if expected == partition {
175 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
176 }
177 }
178 }
179 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800180 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900181 }
182 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800183 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900184 }
185 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800186 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900187 }
188 systemExtSpecific := func(m *Module) bool {
189 return m.SystemExtSpecific()
190 }
191 checkPartition(socSpecific(mod), "vendor")
192 checkPartition(deviceSpecific(mod), "odm")
193 checkPartition(productSpecific(mod), "product")
194 checkPartition(systemExtSpecific(mod), "system_ext")
195 if !partitionDefined && expected != "system" {
196 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
197 " but installed to system partition", variant, name, expected)
198 }
199}
200
201func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400202 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900203 t.Helper()
204 ctx := prepareForCcTest.RunTestWithBp(t, `
205 cc_library {
206 name: "libsystem",
207 }
208 cc_library {
209 name: "libsystem_ext",
210 system_ext_specific: true,
211 }
212 cc_library {
213 name: "libproduct",
214 product_specific: true,
215 }
216 cc_library {
217 name: "libvendor",
218 vendor: true,
219 }
220 cc_library {
221 name: "libodm",
222 device_specific: true,
223 }
224 cc_library {
225 name: "liball_available",
226 vendor_available: true,
227 product_available: true,
228 }
229 cc_library {
230 name: "libsystem_ext_all_available",
231 system_ext_specific: true,
232 vendor_available: true,
233 product_available: true,
234 }
235 cc_library {
236 name: "liball_available_odm",
237 odm_available: true,
238 product_available: true,
239 }
240 cc_library {
241 name: "libproduct_vendoravailable",
242 product_specific: true,
243 vendor_available: true,
244 }
245 cc_library {
246 name: "libproduct_odmavailable",
247 product_specific: true,
248 odm_available: true,
249 }
250 `).TestContext
251
252 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
253 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
254 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
255 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
256 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
257
258 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
259 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
260 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
261
262 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
263 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
264 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
265
266 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
267 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
268 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
269
270 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
271 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
272
273 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
274 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
275}
276
Colin Crossf61d03d2023-11-02 16:56:39 -0700277func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900278 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700279 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800280 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900281 assertArrayString(t, actual, expected)
282}
283
Chris Parsons79d66a52020-06-05 17:26:16 -0400284func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400285 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400286 bp := `
287 cc_test_library {
288 name: "test_lib",
289 srcs: ["test_lib.cpp"],
290 gtest: false,
291 }
292
293 cc_test {
294 name: "main_test",
295 data_libs: ["test_lib"],
296 gtest: false,
297 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400298 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400299
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000300 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400301
302 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700303 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
304 testBinary := testingModule.Module().(*Module).linker.(*testBinary)
305 outputFiles := testingModule.OutputFiles(t, "")
Chris Parsons79d66a52020-06-05 17:26:16 -0400306 if len(outputFiles) != 1 {
307 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
308 return
309 }
310 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800311 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400312 return
313 }
314
315 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400316 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400317
318 if !strings.HasSuffix(outputPath, "/main_test") {
319 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
320 return
321 }
322 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
323 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
324 return
325 }
326}
327
Chris Parsons216e10a2020-07-09 17:12:52 -0400328func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400329 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400330 bp := `
331 cc_test_library {
332 name: "test_lib",
333 srcs: ["test_lib.cpp"],
334 relative_install_path: "foo/bar/baz",
335 gtest: false,
336 }
337
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400338 cc_binary {
339 name: "test_bin",
340 relative_install_path: "foo/bar/baz",
341 compile_multilib: "both",
342 }
343
Chris Parsons216e10a2020-07-09 17:12:52 -0400344 cc_test {
345 name: "main_test",
346 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400347 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400348 gtest: false,
349 }
350 `
351
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000352 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400353
354 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -0700355 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
356 module := testingModule.Module()
Chris Parsons216e10a2020-07-09 17:12:52 -0400357 testBinary := module.(*Module).linker.(*testBinary)
mrziwangabdb2932024-06-18 12:43:41 -0700358 outputFiles := testingModule.OutputFiles(t, "")
Chris Parsons216e10a2020-07-09 17:12:52 -0400359 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400360 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400361 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400362 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800363 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400364 }
365
366 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400367
368 if !strings.HasSuffix(outputPath, "/main_test") {
369 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
370 }
Colin Crossaa255532020-07-03 13:18:24 -0700371 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons216e10a2020-07-09 17:12:52 -0400372 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
373 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400374 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400375 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400376 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
377 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
378 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
379 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400380}
381
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000382func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400383 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000384 bp := `
385 cc_test {
386 name: "main_test",
387 srcs: ["main_test.cpp"],
388 test_suites: [
389 "suite_1",
390 "suite_2",
391 ],
392 gtest: false,
393 }
394 `
395
396 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
397 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
398
399 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
400 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
401 if len(compatEntries) != 2 {
402 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
403 }
404 if compatEntries[0] != "suite_1" {
405 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
406 " but was '%s'", compatEntries[0])
407 }
408 if compatEntries[1] != "suite_2" {
409 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
410 " but was '%s'", compatEntries[1])
411 }
412}
413
414func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400415 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000416 bp := `
417 cc_test_library {
418 name: "main_test_lib",
419 srcs: ["main_test_lib.cpp"],
420 test_suites: [
421 "suite_1",
422 "suite_2",
423 ],
424 gtest: false,
425 }
426 `
427
428 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
429 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
430
431 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
432 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
433 if len(compatEntries) != 2 {
434 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
435 }
436 if compatEntries[0] != "suite_1" {
437 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
438 " but was '%s'", compatEntries[0])
439 }
440 if compatEntries[1] != "suite_2" {
441 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
442 " but was '%s'", compatEntries[1])
443 }
444}
445
Jooyung Hana70f0672019-01-18 15:20:43 +0900446func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400447 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900448 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900449 testCc(t, `
450 cc_library {
451 name: "libllndk",
452 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700453 llndk: {
454 symbol_file: "libllndk.map.txt",
455 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900456 }
457
458 cc_library {
459 name: "libdoubleloadable",
460 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900461 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900462 double_loadable: true,
463 }
464 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900465 // okay to link : double_loadable -> double_loadable
466 testCc(t, `
467 cc_library {
468 name: "libdoubleloadable1",
469 shared_libs: ["libdoubleloadable2"],
470 vendor_available: true,
471 double_loadable: true,
472 }
473
474 cc_library {
475 name: "libdoubleloadable2",
476 vendor_available: true,
477 double_loadable: true,
478 }
479 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900480 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900481 testCc(t, `
482 cc_library {
483 name: "libdoubleloadable",
484 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900485 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900486 double_loadable: true,
487 shared_libs: ["libnondoubleloadable"],
488 }
489
490 cc_library {
491 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900492 vendor_available: true,
493 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900494 double_loadable: true,
495 }
496 `)
497 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
498 testCc(t, `
499 cc_library {
500 name: "libllndk",
501 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700502 llndk: {
503 symbol_file: "libllndk.map.txt",
504 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900505 }
506
507 cc_library {
508 name: "libcoreonly",
509 shared_libs: ["libvendoravailable"],
510 }
511
512 // indirect dependency of LLNDK
513 cc_library {
514 name: "libvendoravailable",
515 vendor_available: true,
516 double_loadable: true,
517 }
518 `)
519}
520
521func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400522 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900523 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900524 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
525 cc_library {
526 name: "libllndk",
527 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700528 llndk: {
529 symbol_file: "libllndk.map.txt",
530 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900531 }
532
533 cc_library {
534 name: "libnondoubleloadable",
535 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900536 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900537 }
538 `)
539
540 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
541 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
542 cc_library {
543 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700544 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900545 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700546 llndk: {
547 symbol_file: "libllndk.map.txt",
548 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900549 }
550
551 cc_library {
552 name: "libnondoubleloadable",
553 vendor_available: true,
554 }
555 `)
556
Jooyung Hana70f0672019-01-18 15:20:43 +0900557 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
558 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
559 cc_library {
560 name: "libllndk",
561 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700562 llndk: {
563 symbol_file: "libllndk.map.txt",
564 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900565 }
566
567 cc_library {
568 name: "libcoreonly",
569 shared_libs: ["libvendoravailable"],
570 }
571
572 // indirect dependency of LLNDK
573 cc_library {
574 name: "libvendoravailable",
575 vendor_available: true,
576 }
577 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900578
579 // The error is not from 'client' but from 'libllndk'
580 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
581 cc_library {
582 name: "client",
583 vendor_available: true,
584 double_loadable: true,
585 shared_libs: ["libllndk"],
586 }
587 cc_library {
588 name: "libllndk",
589 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700590 llndk: {
591 symbol_file: "libllndk.map.txt",
592 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900593 }
594 cc_library {
595 name: "libnondoubleloadable",
596 vendor_available: true,
597 }
598 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800599}
600
Jooyung Han38002912019-05-16 04:01:54 +0900601func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400602 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800603 bp := `
604 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800605 name: "libvendor",
606 vendor: true,
607 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800608 vndk_prebuilt_shared {
609 name: "prevndk",
610 version: "27",
611 target_arch: "arm",
612 binder32bit: true,
613 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900614 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800615 vndk: {
616 enabled: true,
617 },
618 arch: {
619 arm: {
620 srcs: ["liba.so"],
621 },
622 },
623 }
624 cc_library {
625 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700626 llndk: {
627 symbol_file: "libllndk.map.txt",
628 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800629 }
630 cc_library {
631 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700632 llndk: {
633 symbol_file: "libllndkprivate.map.txt",
634 private: true,
635 }
Colin Cross78212242021-01-06 14:51:30 -0800636 }
Colin Cross78212242021-01-06 14:51:30 -0800637 llndk_libraries_txt {
638 name: "llndk.libraries.txt",
639 }
Colin Cross78212242021-01-06 14:51:30 -0800640 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800641
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000642 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900643 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800644 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900645
Colin Crossfb0c16e2019-11-20 17:12:35 -0800646 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900647
Jooyung Han38002912019-05-16 04:01:54 +0900648 tests := []struct {
649 variant string
650 name string
651 expected string
652 }{
Jooyung Han38002912019-05-16 04:01:54 +0900653 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800654 {vendorVariant, "libllndk", "native:vndk"},
Kiyoung Kim9f26fcf2024-05-27 17:25:52 +0900655 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +0900656 {coreVariant, "libllndk", "native:platform"},
657 }
658 for _, test := range tests {
659 t.Run(test.name, func(t *testing.T) {
660 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
661 assertString(t, module.makeLinkType, test.expected)
662 })
663 }
664}
665
Jeff Gaston294356f2017-09-27 17:05:30 -0700666var staticLinkDepOrderTestCases = []struct {
667 // This is a string representation of a map[moduleName][]moduleDependency .
668 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800669 inStatic string
670
671 // This is a string representation of a map[moduleName][]moduleDependency .
672 // It models the dependencies declared in an Android.bp file.
673 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700674
675 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
676 // The keys of allOrdered specify which modules we would like to check.
677 // The values of allOrdered specify the expected result (of the transitive closure of all
678 // dependencies) for each module to test
679 allOrdered string
680
681 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
682 // The keys of outOrdered specify which modules we would like to check.
683 // The values of outOrdered specify the expected result (of the ordered linker command line)
684 // for each module to test.
685 outOrdered string
686}{
687 // Simple tests
688 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800689 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700690 outOrdered: "",
691 },
692 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800693 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700694 outOrdered: "a:",
695 },
696 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800697 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700698 outOrdered: "a:b; b:",
699 },
700 // Tests of reordering
701 {
702 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800703 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700704 outOrdered: "a:b,c,d; b:d; c:d; d:",
705 },
706 {
707 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800708 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700709 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
710 },
711 {
712 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800713 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700714 outOrdered: "a:d,b,e,c; d:b; e:c",
715 },
716 {
717 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800718 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700719 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
720 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
721 },
722 {
723 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800724 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 -0700725 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
726 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
727 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800728 // shared dependencies
729 {
730 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
731 // So, we don't actually have to check that a shared dependency of c will change the order
732 // of a library that depends statically on b and on c. We only need to check that if c has
733 // a shared dependency on b, that that shows up in allOrdered.
734 inShared: "c:b",
735 allOrdered: "c:b",
736 outOrdered: "c:",
737 },
738 {
739 // This test doesn't actually include any shared dependencies but it's a reminder of what
740 // the second phase of the above test would look like
741 inStatic: "a:b,c; c:b",
742 allOrdered: "a:c,b; c:b",
743 outOrdered: "a:c,b; c:b",
744 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700745 // tiebreakers for when two modules specifying different orderings and there is no dependency
746 // to dictate an order
747 {
748 // 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 -0800749 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700750 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
751 },
752 {
753 // 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 -0800754 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 -0700755 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
756 },
757 // Tests involving duplicate dependencies
758 {
759 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800760 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700761 outOrdered: "a:c,b",
762 },
763 {
764 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800765 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700766 outOrdered: "a:d,c,b",
767 },
768 // Tests to confirm the nonexistence of infinite loops.
769 // These cases should never happen, so as long as the test terminates and the
770 // result is deterministic then that should be fine.
771 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800772 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700773 outOrdered: "a:a",
774 },
775 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800776 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700777 allOrdered: "a:b,c; b:c,a; c:a,b",
778 outOrdered: "a:b; b:c; c:a",
779 },
780 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800781 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700782 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
783 outOrdered: "a:c,b; b:a,c; c:b,a",
784 },
785}
786
787// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
788func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
789 // convert from "a:b,c; d:e" to "a:b,c;d:e"
790 strippedText := strings.Replace(text, " ", "", -1)
791 if len(strippedText) < 1 {
792 return []android.Path{}, make(map[android.Path][]android.Path, 0)
793 }
794 allDeps = make(map[android.Path][]android.Path, 0)
795
796 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
797 moduleTexts := strings.Split(strippedText, ";")
798
799 outputForModuleName := func(moduleName string) android.Path {
800 return android.PathForTesting(moduleName)
801 }
802
803 for _, moduleText := range moduleTexts {
804 // convert from "a:b,c" to ["a", "b,c"]
805 components := strings.Split(moduleText, ":")
806 if len(components) != 2 {
807 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
808 }
809 moduleName := components[0]
810 moduleOutput := outputForModuleName(moduleName)
811 modulesInOrder = append(modulesInOrder, moduleOutput)
812
813 depString := components[1]
814 // convert from "b,c" to ["b", "c"]
815 depNames := strings.Split(depString, ",")
816 if len(depString) < 1 {
817 depNames = []string{}
818 }
819 var deps []android.Path
820 for _, depName := range depNames {
821 deps = append(deps, outputForModuleName(depName))
822 }
823 allDeps[moduleOutput] = deps
824 }
825 return modulesInOrder, allDeps
826}
827
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800828func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400829 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700830 ctx := testCc(t, `
831 cc_library {
832 name: "a",
833 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900834 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700835 }
836 cc_library {
837 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900838 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700839 }
840 cc_library {
841 name: "c",
842 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900843 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700844 }
845 cc_library {
846 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900847 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700848 }
849
850 `)
851
Colin Cross7113d202019-11-20 16:39:12 -0800852 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700853 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800854 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
855 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400856 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700857
858 if !reflect.DeepEqual(actual, expected) {
859 t.Errorf("staticDeps orderings were not propagated correctly"+
860 "\nactual: %v"+
861 "\nexpected: %v",
862 actual,
863 expected,
864 )
865 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900866}
Jeff Gaston294356f2017-09-27 17:05:30 -0700867
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800868func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400869 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800870 ctx := testCc(t, `
871 cc_library {
872 name: "a",
873 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900874 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800875 }
876 cc_library {
877 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900878 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800879 }
880 cc_library {
881 name: "c",
882 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900883 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800884 }
885
886 `)
887
Colin Cross7113d202019-11-20 16:39:12 -0800888 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800889 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800890 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
891 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400892 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800893
894 if !reflect.DeepEqual(actual, expected) {
895 t.Errorf("staticDeps orderings did not account for shared libs"+
896 "\nactual: %v"+
897 "\nexpected: %v",
898 actual,
899 expected,
900 )
901 }
902}
903
Jooyung Hanb04a4992020-03-13 18:57:35 +0900904func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700905 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900906 if !reflect.DeepEqual(actual, expected) {
907 t.Errorf(message+
908 "\nactual: %v"+
909 "\nexpected: %v",
910 actual,
911 expected,
912 )
913 }
914}
915
Jooyung Han61b66e92020-03-21 14:21:46 +0000916func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400917 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800918 result := prepareForCcTest.RunTestWithBp(t, `
919 cc_library {
920 name: "libllndk",
921 stubs: { versions: ["1", "2"] },
922 llndk: {
923 symbol_file: "libllndk.map.txt",
924 },
925 export_include_dirs: ["include"],
926 }
927
928 cc_prebuilt_library_shared {
929 name: "libllndkprebuilt",
930 stubs: { versions: ["1", "2"] },
931 llndk: {
932 symbol_file: "libllndkprebuilt.map.txt",
933 },
934 }
935
936 cc_library {
937 name: "libllndk_with_external_headers",
938 stubs: { versions: ["1", "2"] },
939 llndk: {
940 symbol_file: "libllndk.map.txt",
941 export_llndk_headers: ["libexternal_llndk_headers"],
942 },
943 header_libs: ["libexternal_headers"],
944 export_header_lib_headers: ["libexternal_headers"],
945 }
946 cc_library_headers {
947 name: "libexternal_headers",
948 export_include_dirs: ["include"],
949 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900950 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800951 }
952 cc_library_headers {
953 name: "libexternal_llndk_headers",
954 export_include_dirs: ["include_llndk"],
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800955 export_system_include_dirs: ["include_system_llndk"],
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800956 llndk: {
957 symbol_file: "libllndk.map.txt",
958 },
959 vendor_available: true,
960 }
961
962 cc_library {
963 name: "libllndk_with_override_headers",
964 stubs: { versions: ["1", "2"] },
965 llndk: {
966 symbol_file: "libllndk.map.txt",
967 override_export_include_dirs: ["include_llndk"],
968 },
969 export_include_dirs: ["include"],
970 }
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800971
972 cc_library {
973 name: "libllndk_with_system_headers",
974 llndk: {
975 symbol_file: "libllndk.map.txt",
976 export_llndk_headers: ["libexternal_llndk_headers"],
977 export_headers_as_system: true,
978 },
979 export_include_dirs: ["include"],
980 export_system_include_dirs: ["include_system"],
981 }
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800982 `)
983 actual := result.ModuleVariantsForTests("libllndk")
984 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900985 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800986 actual = append(actual[:i], actual[i+1:]...)
987 i--
988 }
989 }
990 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900991 "android_vendor_arm64_armv8-a_shared",
992 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800993 }
994 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
995
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900996 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Han33eb6152024-03-11 15:46:48 +0900997 android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800998
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800999 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001000 t.Helper()
1001 m := result.ModuleForTests(module, variant).Module()
Colin Cross5a377182023-12-14 14:46:23 -08001002 f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001003 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1004 expectedDirs, f.IncludeDirs)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001005 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1006 expectedSystemDirs, f.SystemIncludeDirs)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001007 }
1008
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001009 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
1010 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
1011 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
1012 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
1013 []string{"include_system_llndk"}, "include_llndk")
1014 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
1015 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
1016 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
1017 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
1018 []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001019
1020 checkAbiLinkerIncludeDirs := func(module string) {
1021 t.Helper()
1022 coreModule := result.ModuleForTests(module, coreVariant)
1023 abiCheckFlags := ""
1024 for _, output := range coreModule.AllOutputs() {
1025 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1026 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1027 }
1028 }
1029 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
1030 vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001031 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001032 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001033 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001034 }
1035 checkAbiLinkerIncludeDirs("libllndk")
1036 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1037 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001038 checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001039}
1040
Jiyong Parka46a4d52017-12-14 19:54:34 +09001041func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001042 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001043 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001044 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001045 name: "libllndk_headers",
1046 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001047 llndk: {
1048 llndk_headers: true,
1049 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001050 }
1051 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001052 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001053 llndk: {
1054 symbol_file: "libllndk.map.txt",
1055 export_llndk_headers: ["libllndk_headers"],
1056 }
Colin Cross0477b422020-10-13 18:43:54 -07001057 }
1058
1059 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001060 name: "libvendor",
1061 shared_libs: ["libllndk"],
1062 vendor: true,
1063 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001064 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001065 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001066 }
1067 `)
1068
1069 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001070 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001071 cflags := cc.Args["cFlags"]
1072 if !strings.Contains(cflags, "-Imy_include") {
1073 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1074 }
1075}
1076
Logan Chien43d34c32017-12-20 01:17:32 +08001077func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1078 actual := module.Properties.AndroidMkRuntimeLibs
1079 if !reflect.DeepEqual(actual, expected) {
1080 t.Errorf("incorrect runtime_libs for shared libs"+
1081 "\nactual: %v"+
1082 "\nexpected: %v",
1083 actual,
1084 expected,
1085 )
1086 }
1087}
1088
1089const runtimeLibAndroidBp = `
1090 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001091 name: "liball_available",
1092 vendor_available: true,
1093 product_available: true,
1094 no_libcrt : true,
1095 nocrt : true,
1096 system_shared_libs : [],
1097 }
1098 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001099 name: "libvendor_available1",
1100 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001101 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001102 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001103 nocrt : true,
1104 system_shared_libs : [],
1105 }
1106 cc_library {
1107 name: "libvendor_available2",
1108 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001109 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001110 target: {
1111 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001112 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001113 }
1114 },
Yi Konge7fe9912019-06-02 00:53:50 -07001115 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001116 nocrt : true,
1117 system_shared_libs : [],
1118 }
1119 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001120 name: "libproduct_vendor",
1121 product_specific: true,
1122 vendor_available: true,
1123 no_libcrt : true,
1124 nocrt : true,
1125 system_shared_libs : [],
1126 }
1127 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001128 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001129 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001130 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001131 nocrt : true,
1132 system_shared_libs : [],
1133 }
1134 cc_library {
1135 name: "libvendor1",
1136 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001137 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001138 nocrt : true,
1139 system_shared_libs : [],
1140 }
1141 cc_library {
1142 name: "libvendor2",
1143 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001144 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001145 no_libcrt : true,
1146 nocrt : true,
1147 system_shared_libs : [],
1148 }
1149 cc_library {
1150 name: "libproduct_available1",
1151 product_available: true,
1152 runtime_libs: ["liball_available"],
1153 no_libcrt : true,
1154 nocrt : true,
1155 system_shared_libs : [],
1156 }
1157 cc_library {
1158 name: "libproduct1",
1159 product_specific: true,
1160 no_libcrt : true,
1161 nocrt : true,
1162 system_shared_libs : [],
1163 }
1164 cc_library {
1165 name: "libproduct2",
1166 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001167 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001168 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001169 nocrt : true,
1170 system_shared_libs : [],
1171 }
1172`
1173
1174func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001175 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001176 ctx := testCc(t, runtimeLibAndroidBp)
1177
1178 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001179 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001180
Justin Yun8a2600c2020-12-07 12:44:03 +09001181 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1182 checkRuntimeLibs(t, []string{"liball_available"}, module)
1183
1184 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1185 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001186
1187 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001188 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001189
1190 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1191 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001192 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001193
Justin Yun8a2600c2020-12-07 12:44:03 +09001194 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1195 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001196
1197 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001198 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001199
1200 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1201 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001202 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001203
1204 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1205 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1206
1207 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001208 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001209}
1210
1211func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001212 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001213 ctx := testCc(t, runtimeLibAndroidBp)
1214
Colin Cross7113d202019-11-20 16:39:12 -08001215 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001216 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1217 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001218
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001219 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001220 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001221 checkRuntimeLibs(t, nil, module)
1222}
1223
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001224func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001225 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001226 actual := module.Properties.AndroidMkStaticLibs
1227 if !reflect.DeepEqual(actual, expected) {
1228 t.Errorf("incorrect static_libs"+
1229 "\nactual: %v"+
1230 "\nexpected: %v",
1231 actual,
1232 expected,
1233 )
1234 }
1235}
1236
1237const staticLibAndroidBp = `
1238 cc_library {
1239 name: "lib1",
1240 }
1241 cc_library {
1242 name: "lib2",
1243 static_libs: ["lib1"],
1244 }
1245`
1246
1247func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001248 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001249 ctx := testCc(t, staticLibAndroidBp)
1250
1251 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001252 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001253 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001254 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001255
1256 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001257 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001258 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1259 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001260 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001261}
1262
Jiyong Parkd08b6972017-09-26 10:50:54 +09001263var compilerFlagsTestCases = []struct {
1264 in string
1265 out bool
1266}{
1267 {
1268 in: "a",
1269 out: false,
1270 },
1271 {
1272 in: "-a",
1273 out: true,
1274 },
1275 {
1276 in: "-Ipath/to/something",
1277 out: false,
1278 },
1279 {
1280 in: "-isystempath/to/something",
1281 out: false,
1282 },
1283 {
1284 in: "--coverage",
1285 out: false,
1286 },
1287 {
1288 in: "-include a/b",
1289 out: true,
1290 },
1291 {
1292 in: "-include a/b c/d",
1293 out: false,
1294 },
1295 {
1296 in: "-DMACRO",
1297 out: true,
1298 },
1299 {
1300 in: "-DMAC RO",
1301 out: false,
1302 },
1303 {
1304 in: "-a -b",
1305 out: false,
1306 },
1307 {
1308 in: "-DMACRO=definition",
1309 out: true,
1310 },
1311 {
1312 in: "-DMACRO=defi nition",
1313 out: true, // TODO(jiyong): this should be false
1314 },
1315 {
1316 in: "-DMACRO(x)=x + 1",
1317 out: true,
1318 },
1319 {
1320 in: "-DMACRO=\"defi nition\"",
1321 out: true,
1322 },
1323}
1324
1325type mockContext struct {
1326 BaseModuleContext
1327 result bool
1328}
1329
1330func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1331 // CheckBadCompilerFlags calls this function when the flag should be rejected
1332 ctx.result = false
1333}
1334
1335func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001336 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001337 for _, testCase := range compilerFlagsTestCases {
1338 ctx := &mockContext{result: true}
1339 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1340 if ctx.result != testCase.out {
1341 t.Errorf("incorrect output:")
1342 t.Errorf(" input: %#v", testCase.in)
1343 t.Errorf(" expected: %#v", testCase.out)
1344 t.Errorf(" got: %#v", ctx.result)
1345 }
1346 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001347}
Jiyong Park374510b2018-03-19 18:23:01 +09001348
Jiyong Park37b25202018-07-11 10:49:27 +09001349func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001350 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001351 ctx := testCc(t, `
1352 cc_library_shared {
1353 name: "librecovery",
1354 recovery: true,
1355 }
1356 cc_library_shared {
1357 name: "librecovery32",
1358 recovery: true,
1359 compile_multilib:"32",
1360 }
Jiyong Park5baac542018-08-28 09:55:37 +09001361 cc_library_shared {
1362 name: "libHalInRecovery",
1363 recovery_available: true,
1364 vendor: true,
1365 }
Jiyong Park37b25202018-07-11 10:49:27 +09001366 `)
1367
1368 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001369 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001370 if len(variants) != 1 || !android.InList(arm64, variants) {
1371 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1372 }
1373
1374 variants = ctx.ModuleVariantsForTests("librecovery32")
1375 if android.InList(arm64, variants) {
1376 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1377 }
Jiyong Park5baac542018-08-28 09:55:37 +09001378
1379 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1380 if !recoveryModule.Platform() {
1381 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1382 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001383}
Jiyong Park5baac542018-08-28 09:55:37 +09001384
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001385func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001386 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001387 bp := `
1388 cc_prebuilt_test_library_shared {
1389 name: "test_lib",
1390 relative_install_path: "foo/bar/baz",
1391 srcs: ["srcpath/dontusethispath/baz.so"],
1392 }
1393
1394 cc_test {
1395 name: "main_test",
1396 data_libs: ["test_lib"],
1397 gtest: false,
1398 }
1399 `
1400
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001401 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001402
1403 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07001404 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
1405 module := testingModule.Module()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001406 testBinary := module.(*Module).linker.(*testBinary)
mrziwangabdb2932024-06-18 12:43:41 -07001407 outputFiles := testingModule.OutputFiles(t, "")
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001408 if len(outputFiles) != 1 {
1409 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1410 }
1411 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001412 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001413 }
1414
1415 outputPath := outputFiles[0].String()
1416
1417 if !strings.HasSuffix(outputPath, "/main_test") {
1418 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1419 }
Colin Crossaa255532020-07-03 13:18:24 -07001420 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001421 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1422 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1423 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1424 }
1425}
1426
Jiyong Park7ed9de32018-10-15 22:25:07 +09001427func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001428 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001429 ctx := testCc(t, `
1430 cc_library_shared {
1431 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001432 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001433 stubs: {
1434 symbol_file: "foo.map.txt",
1435 versions: ["1", "2", "3"],
1436 },
1437 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001438
Jiyong Park7ed9de32018-10-15 22:25:07 +09001439 cc_library_shared {
1440 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001441 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001442 shared_libs: ["libFoo#1"],
1443 }`)
1444
1445 variants := ctx.ModuleVariantsForTests("libFoo")
1446 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001447 "android_arm64_armv8-a_shared",
1448 "android_arm64_armv8-a_shared_1",
1449 "android_arm64_armv8-a_shared_2",
1450 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001451 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001452 "android_arm_armv7-a-neon_shared",
1453 "android_arm_armv7-a-neon_shared_1",
1454 "android_arm_armv7-a-neon_shared_2",
1455 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001456 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001457 }
1458 variantsMismatch := false
1459 if len(variants) != len(expectedVariants) {
1460 variantsMismatch = true
1461 } else {
1462 for _, v := range expectedVariants {
1463 if !inList(v, variants) {
1464 variantsMismatch = false
1465 }
1466 }
1467 }
1468 if variantsMismatch {
1469 t.Errorf("variants of libFoo expected:\n")
1470 for _, v := range expectedVariants {
1471 t.Errorf("%q\n", v)
1472 }
1473 t.Errorf(", but got:\n")
1474 for _, v := range variants {
1475 t.Errorf("%q\n", v)
1476 }
1477 }
1478
Colin Cross7113d202019-11-20 16:39:12 -08001479 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001480 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001481 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001482 if !strings.Contains(libFlags, libFoo1StubPath) {
1483 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1484 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001485
Colin Cross7113d202019-11-20 16:39:12 -08001486 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001487 cFlags := libBarCompileRule.Args["cFlags"]
1488 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1489 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1490 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1491 }
Jiyong Park37b25202018-07-11 10:49:27 +09001492}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001493
Liz Kammer48cdbeb2023-03-17 10:17:50 -04001494func TestStubsForLibraryInMultipleApexes(t *testing.T) {
1495 t.Parallel()
1496 ctx := testCc(t, `
1497 cc_library_shared {
1498 name: "libFoo",
1499 srcs: ["foo.c"],
1500 stubs: {
1501 symbol_file: "foo.map.txt",
1502 versions: ["current"],
1503 },
1504 apex_available: ["bar", "a1"],
1505 }
1506
1507 cc_library_shared {
1508 name: "libBar",
1509 srcs: ["bar.c"],
1510 shared_libs: ["libFoo"],
1511 apex_available: ["a1"],
1512 }
1513
1514 cc_library_shared {
1515 name: "libA1",
1516 srcs: ["a1.c"],
1517 shared_libs: ["libFoo"],
1518 apex_available: ["a1"],
1519 }
1520
1521 cc_library_shared {
1522 name: "libBarA1",
1523 srcs: ["bara1.c"],
1524 shared_libs: ["libFoo"],
1525 apex_available: ["bar", "a1"],
1526 }
1527
1528 cc_library_shared {
1529 name: "libAnyApex",
1530 srcs: ["anyApex.c"],
1531 shared_libs: ["libFoo"],
1532 apex_available: ["//apex_available:anyapex"],
1533 }
1534
1535 cc_library_shared {
1536 name: "libBaz",
1537 srcs: ["baz.c"],
1538 shared_libs: ["libFoo"],
1539 apex_available: ["baz"],
1540 }
1541
1542 cc_library_shared {
1543 name: "libQux",
1544 srcs: ["qux.c"],
1545 shared_libs: ["libFoo"],
1546 apex_available: ["qux", "bar"],
1547 }`)
1548
1549 variants := ctx.ModuleVariantsForTests("libFoo")
1550 expectedVariants := []string{
1551 "android_arm64_armv8-a_shared",
1552 "android_arm64_armv8-a_shared_current",
1553 "android_arm_armv7-a-neon_shared",
1554 "android_arm_armv7-a-neon_shared_current",
1555 }
1556 variantsMismatch := false
1557 if len(variants) != len(expectedVariants) {
1558 variantsMismatch = true
1559 } else {
1560 for _, v := range expectedVariants {
1561 if !inList(v, variants) {
1562 variantsMismatch = false
1563 }
1564 }
1565 }
1566 if variantsMismatch {
1567 t.Errorf("variants of libFoo expected:\n")
1568 for _, v := range expectedVariants {
1569 t.Errorf("%q\n", v)
1570 }
1571 t.Errorf(", but got:\n")
1572 for _, v := range variants {
1573 t.Errorf("%q\n", v)
1574 }
1575 }
1576
1577 linkAgainstFoo := []string{"libBarA1"}
1578 linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
1579
1580 libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
1581 for _, lib := range linkAgainstFoo {
1582 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1583 libFlags := libLinkRule.Args["libFlags"]
1584 if !strings.Contains(libFlags, libFooPath) {
1585 t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
1586 }
1587 }
1588
1589 libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
1590 for _, lib := range linkAgainstFooStubs {
1591 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1592 libFlags := libLinkRule.Args["libFlags"]
1593 if !strings.Contains(libFlags, libFooStubPath) {
1594 t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
1595 }
1596 }
1597}
1598
Jooyung Hanb04a4992020-03-13 18:57:35 +09001599func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001600 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001601 for _, tc := range []struct{ moduleName, expected string }{
1602 {"libc", "__LIBC_API__"},
1603 {"libfoo", "__LIBFOO_API__"},
1604 {"libfoo@1", "__LIBFOO_1_API__"},
1605 {"libfoo-v1", "__LIBFOO_V1_API__"},
1606 {"libfoo.v1", "__LIBFOO_V1_API__"},
1607 } {
1608 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1609 }
1610}
1611
Liz Kammer83cf81b2022-09-22 08:24:20 -04001612func pathsToBase(paths android.Paths) []string {
1613 var ret []string
1614 for _, p := range paths {
1615 ret = append(ret, p.Base())
1616 }
1617 return ret
1618}
1619
1620func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001621 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001622 ctx := testCc(t, `
1623 cc_library_static {
1624 name: "foo",
1625 srcs: ["foo.c"],
1626 }
1627
1628 cc_library_static {
1629 name: "bar",
1630 srcs: ["bar.c"],
1631 }
1632
1633 cc_library_shared {
1634 name: "qux",
1635 srcs: ["qux.c"],
1636 }
1637
1638 cc_library_static {
1639 name: "baz",
1640 srcs: ["baz.c"],
1641 static_libs: ["foo"],
1642 shared_libs: ["qux"],
1643 whole_static_libs: ["bar"],
1644 }`)
1645
1646 variant := "android_arm64_armv8-a_static"
1647 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1648
1649 // For static libraries, the object files of a whole static dep are included in the archive
1650 // directly
1651 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1652 t.Errorf("Expected input objects %q, got %q", w, g)
1653 }
1654
1655 // non whole static dependencies are not linked into the archive
1656 if len(arRule.Implicits) > 0 {
1657 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1658 }
1659}
1660
1661func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001662 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001663 ctx := testCc(t, `
1664 cc_library_static {
1665 name: "foo",
1666 srcs: ["foo.c"],
1667 }
1668
1669 cc_library_static {
1670 name: "bar",
1671 srcs: ["bar.c"],
1672 }
1673
1674 cc_library_shared {
1675 name: "qux",
1676 srcs: ["qux.c"],
1677 }
1678
1679 cc_library_shared {
1680 name: "baz",
1681 srcs: ["baz.c"],
1682 static_libs: ["foo"],
1683 shared_libs: ["qux"],
1684 whole_static_libs: ["bar"],
1685 }`)
1686
1687 variant := "android_arm64_armv8-a_shared"
1688 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1689 libFlags := linkRule.Args["libFlags"]
1690 // When dynamically linking, we expect static dependencies to be found on the command line
1691 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1692 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1693 }
1694 // When dynamically linking, we expect whole static dependencies to be found on the command line
1695 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1696 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1697 }
1698
1699 // When dynamically linking, we expect shared dependencies to be found on the command line
1700 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1701 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1702 }
1703
1704 // We should only have the objects from the shared library srcs, not the whole static dependencies
1705 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1706 t.Errorf("Expected input objects %q, got %q", w, g)
1707 }
1708}
1709
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001710func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001711 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001712 ctx := testCc(t, `
1713 cc_binary {
1714 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001715 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001716 static_executable: true,
1717 }`)
1718
Colin Cross7113d202019-11-20 16:39:12 -08001719 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001720 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1721 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001722 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001723 for _, lib := range systemStaticLibs {
1724 if !strings.Contains(libFlags, lib) {
1725 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1726 }
1727 }
1728 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1729 for _, lib := range systemSharedLibs {
1730 if strings.Contains(libFlags, lib) {
1731 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1732 }
1733 }
1734}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001735
1736func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001737 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001738 ctx := testCc(t, `
1739 cc_binary {
1740 name: "mybin",
1741 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001742 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001743 static_executable: true,
1744 stl: "none",
1745 }
1746
1747 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001748 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001749 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001750 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001751 stl: "none",
1752 }
1753
1754 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001755 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001756 srcs: ["foo.c"],
1757 stl: "none",
1758 stubs: {
1759 versions: ["1"],
1760 },
1761 }`)
1762
Colin Cross0de8a1e2020-09-18 14:15:30 -07001763 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1764 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001765 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001766
1767 if !reflect.DeepEqual(actual, expected) {
1768 t.Errorf("staticDeps orderings were not propagated correctly"+
1769 "\nactual: %v"+
1770 "\nexpected: %v",
1771 actual,
1772 expected,
1773 )
1774 }
1775}
Jooyung Han38002912019-05-16 04:01:54 +09001776
Jooyung Hand48f3c32019-08-23 11:18:57 +09001777func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001778 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001779 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1780 cc_library {
1781 name: "libA",
1782 srcs: ["foo.c"],
1783 shared_libs: ["libB"],
1784 stl: "none",
1785 }
1786
1787 cc_library {
1788 name: "libB",
1789 srcs: ["foo.c"],
1790 enabled: false,
1791 stl: "none",
1792 }
1793 `)
1794}
1795
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001796func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1797 bp := `
1798 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001799 name: "test_afl_fuzz_target",
1800 srcs: ["foo.c"],
1801 host_supported: true,
1802 static_libs: [
1803 "afl_fuzz_static_lib",
1804 ],
1805 shared_libs: [
1806 "afl_fuzz_shared_lib",
1807 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001808 fuzzing_frameworks: {
1809 afl: true,
1810 libfuzzer: false,
1811 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001812 }
1813 cc_library {
1814 name: "afl_fuzz_static_lib",
1815 host_supported: true,
1816 srcs: ["static_file.c"],
1817 }
1818 cc_library {
1819 name: "libfuzzer_only_static_lib",
1820 host_supported: true,
1821 srcs: ["static_file.c"],
1822 }
1823 cc_library {
1824 name: "afl_fuzz_shared_lib",
1825 host_supported: true,
1826 srcs: ["shared_file.c"],
1827 static_libs: [
1828 "second_static_lib",
1829 ],
1830 }
1831 cc_library_headers {
1832 name: "libafl_headers",
1833 vendor_available: true,
1834 host_supported: true,
1835 export_include_dirs: [
1836 "include",
1837 "instrumentation",
1838 ],
1839 }
1840 cc_object {
1841 name: "afl-compiler-rt",
1842 vendor_available: true,
1843 host_supported: true,
1844 cflags: [
1845 "-fPIC",
1846 ],
1847 srcs: [
1848 "instrumentation/afl-compiler-rt.o.c",
1849 ],
1850 }
1851 cc_library {
1852 name: "second_static_lib",
1853 host_supported: true,
1854 srcs: ["second_file.c"],
1855 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001856 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001857 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001858 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001859 srcs: [
1860 "aflpp_driver.c",
1861 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001862 }`
1863
1864 testEnv := map[string]string{
1865 "FUZZ_FRAMEWORK": "AFL",
1866 }
1867
1868 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001869
1870 checkPcGuardFlag := func(
1871 modName string, variantName string, shouldHave bool) {
1872 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1873
1874 cFlags, ok := cc.Args["cFlags"]
1875 if !ok {
1876 t.Errorf("Could not find cFlags for module %s and variant %s",
1877 modName, variantName)
1878 }
1879
1880 if strings.Contains(
1881 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1882 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1883 "Test failed for module %s and variant %s",
1884 !shouldHave, shouldHave, modName, variantName)
1885 }
1886 }
1887
Cory Barkera1da26f2022-06-07 20:12:06 +00001888 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001889 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001890
1891 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001892 checkPcGuardFlag(moduleName, variant+"_static", false)
1893 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001894
1895 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001896 checkPcGuardFlag(moduleName, variant+"_static", false)
1897 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001898
1899 ctx.ModuleForTests("afl_fuzz_shared_lib",
1900 "android_arm64_armv8-a_shared").Rule("cc")
1901 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001902 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1903}
1904
1905func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001906 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001907 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1908}
1909
1910func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001911 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001912 if runtime.GOOS != "linux" {
1913 t.Skip("requires linux")
1914 }
1915
1916 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001917}
1918
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001919// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1920// correctly.
1921func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001922 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001923 ctx := testCc(t, `
1924 cc_fuzz {
1925 name: "fuzz_smoke_test",
1926 srcs: ["foo.c"],
1927 }`)
1928
Paul Duffin075c4172019-12-19 19:06:13 +00001929 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001930 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1931}
1932
Jooyung Han38002912019-05-16 04:01:54 +09001933func assertString(t *testing.T, got, expected string) {
1934 t.Helper()
1935 if got != expected {
1936 t.Errorf("expected %q got %q", expected, got)
1937 }
1938}
1939
1940func assertArrayString(t *testing.T, got, expected []string) {
1941 t.Helper()
1942 if len(got) != len(expected) {
1943 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1944 return
1945 }
1946 for i := range got {
1947 if got[i] != expected[i] {
1948 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1949 i, expected[i], expected, got[i], got)
1950 return
1951 }
1952 }
1953}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001954
Jooyung Han0302a842019-10-30 18:43:49 +09001955func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1956 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001957 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001958}
1959
Colin Crosse1bb5d02019-09-24 14:55:04 -07001960func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001961 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001962 ctx := testCc(t, `
1963 cc_defaults {
1964 name: "defaults",
1965 srcs: ["foo.c"],
1966 static: {
1967 srcs: ["bar.c"],
1968 },
1969 shared: {
1970 srcs: ["baz.c"],
1971 },
1972 }
1973
1974 cc_library_static {
1975 name: "libstatic",
1976 defaults: ["defaults"],
1977 }
1978
1979 cc_library_shared {
1980 name: "libshared",
1981 defaults: ["defaults"],
1982 }
1983
1984 cc_library {
1985 name: "libboth",
1986 defaults: ["defaults"],
1987 }
1988
1989 cc_binary {
1990 name: "binary",
1991 defaults: ["defaults"],
1992 }`)
1993
Colin Cross7113d202019-11-20 16:39:12 -08001994 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001995 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1996 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
1997 }
Colin Cross7113d202019-11-20 16:39:12 -08001998 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001999 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2000 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2001 }
Colin Cross7113d202019-11-20 16:39:12 -08002002 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002003 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2004 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2005 }
2006
Colin Cross7113d202019-11-20 16:39:12 -08002007 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002008 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2009 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2010 }
Colin Cross7113d202019-11-20 16:39:12 -08002011 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002012 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2013 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2014 }
2015}
Colin Crosseabaedd2020-02-06 17:01:55 -08002016
2017func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002018 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08002019 bp := `
2020 cc_defaults {
2021 name: "libfoo_defaults",
2022 srcs: ["foo.c"],
2023 cppflags: ["-DFOO"],
2024 product_variables: {
2025 debuggable: {
2026 cppflags: ["-DBAR"],
2027 },
2028 },
2029 }
2030
2031 cc_library {
2032 name: "libfoo",
2033 defaults: ["libfoo_defaults"],
2034 }
2035 `
2036
Paul Duffin8567f222021-03-23 00:02:06 +00002037 result := android.GroupFixturePreparers(
2038 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002039 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08002040
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002041 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2042 variables.Debuggable = BoolPtr(true)
2043 }),
2044 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08002045
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002046 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00002047 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08002048}
Colin Crosse4f6eba2020-09-22 18:11:25 -07002049
2050func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
2051 t.Parallel()
2052 bp := `
2053 cc_library_static {
2054 name: "libfoo",
2055 srcs: ["foo.c"],
2056 whole_static_libs: ["libbar"],
2057 }
2058
2059 cc_library_static {
2060 name: "libbar",
2061 whole_static_libs: ["libmissing"],
2062 }
2063 `
2064
Paul Duffin8567f222021-03-23 00:02:06 +00002065 result := android.GroupFixturePreparers(
2066 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002067 android.PrepareForTestWithAllowMissingDependencies,
2068 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002069
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002070 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002071 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002072
Paul Duffine84b1332021-03-12 11:59:43 +00002073 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07002074
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002075 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002076 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07002077}
Colin Crosse9fe2942020-11-10 18:12:15 -08002078
2079func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002080 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08002081 bp := `
2082 cc_binary {
2083 name: "bin",
2084 host_supported: true,
2085 shared_libs: ["libshared"],
2086 runtime_libs: ["libruntime"],
2087 srcs: [":gen"],
2088 }
2089
2090 cc_library_shared {
2091 name: "libshared",
2092 host_supported: true,
2093 shared_libs: ["libtransitive"],
2094 }
2095
2096 cc_library_shared {
2097 name: "libtransitive",
2098 host_supported: true,
2099 }
2100
2101 cc_library_shared {
2102 name: "libruntime",
2103 host_supported: true,
2104 }
2105
2106 cc_binary_host {
2107 name: "tool",
2108 srcs: ["foo.cpp"],
2109 }
2110
2111 genrule {
2112 name: "gen",
2113 tools: ["tool"],
2114 out: ["gen.cpp"],
2115 cmd: "$(location tool) $(out)",
2116 }
2117 `
2118
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002119 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002120 ctx := testCcWithConfig(t, config)
2121
2122 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2123 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2124 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2125 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2126 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2127
2128 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2129 t.Errorf("expected host bin dependency %q, got %q", w, g)
2130 }
2131
2132 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2133 t.Errorf("expected host bin dependency %q, got %q", w, g)
2134 }
2135
2136 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2137 t.Errorf("expected host bin dependency %q, got %q", w, g)
2138 }
2139
2140 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2141 t.Errorf("expected host bin dependency %q, got %q", w, g)
2142 }
2143
2144 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2145 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2146 }
2147
2148 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2149 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2150 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2151 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2152
2153 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2154 t.Errorf("expected device bin dependency %q, got %q", w, g)
2155 }
2156
2157 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2158 t.Errorf("expected device bin dependency %q, got %q", w, g)
2159 }
2160
2161 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2162 t.Errorf("expected device bin dependency %q, got %q", w, g)
2163 }
2164
2165 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2166 t.Errorf("expected device bin dependency %q, got %q", w, g)
2167 }
2168
2169 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2170 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2171 }
2172
2173}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002174
2175func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002176 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002177 ctx := testCc(t, `
2178 cc_library_shared {
2179 name: "libclient",
2180 srcs: ["foo.c"],
2181 shared_libs: ["libfoo#1"],
2182 }
2183
2184 cc_library_shared {
2185 name: "libfoo",
2186 srcs: ["foo.c"],
2187 shared_libs: ["libbar"],
2188 export_shared_lib_headers: ["libbar"],
2189 stubs: {
2190 symbol_file: "foo.map.txt",
2191 versions: ["1", "2", "3"],
2192 },
2193 }
2194
2195 cc_library_shared {
2196 name: "libbar",
2197 export_include_dirs: ["include/libbar"],
2198 srcs: ["foo.c"],
2199 }`)
2200
2201 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2202
2203 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2204 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2205 }
2206}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002207
Vinh Tran09581952023-05-16 16:03:20 -04002208func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002209 t.Parallel()
2210 ctx := android.GroupFixturePreparers(
2211 prepareForCcTest,
2212 aidl_library.PrepareForTestWithAidlLibrary,
2213 android.MockFS{
2214 "package_bar/Android.bp": []byte(`
2215 aidl_library {
2216 name: "bar",
2217 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002218 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002219 strip_import_prefix: "x",
2220 }
2221 `)}.AddToFixture(),
2222 android.MockFS{
2223 "package_foo/Android.bp": []byte(`
2224 aidl_library {
2225 name: "foo",
2226 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002227 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002228 strip_import_prefix: "a",
2229 deps: ["bar"],
2230 }
2231 cc_library {
2232 name: "libfoo",
2233 aidl: {
2234 libs: ["foo"],
2235 }
2236 }
2237 `),
2238 }.AddToFixture(),
2239 ).RunTest(t).TestContext
2240
2241 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002242
2243 android.AssertPathsRelativeToTopEquals(
2244 t,
2245 "aidl headers",
2246 []string{
2247 "package_bar/x/HeaderBar.aidl",
2248 "package_foo/a/HeaderFoo.aidl",
2249 "package_foo/a/b/Foo.aidl",
2250 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2251 },
2252 libfoo.Rule("aidl_library").Implicits,
2253 )
2254
Colin Crossf61d03d2023-11-02 16:56:39 -07002255 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002256 aidlCommand := manifest.Commands[0].GetCommand()
2257
2258 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2259 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2260 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2261 }
2262
2263 outputs := strings.Join(libfoo.AllOutputs(), " ")
2264
Vinh Tran09581952023-05-16 16:03:20 -04002265 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2266 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2267 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002268 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2269 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002270 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2271 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2272 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002273 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2274}
2275
Jooyung Hane197d8b2021-01-05 10:33:16 +09002276func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002277 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002278 ctx := android.GroupFixturePreparers(
2279 prepareForCcTest,
2280 aidl_library.PrepareForTestWithAidlLibrary,
2281 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002282 cc_library {
2283 name: "libfoo",
2284 srcs: ["a/Foo.aidl"],
2285 aidl: { flags: ["-Werror"], },
2286 }
2287 `)
2288
2289 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002290 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002291 aidlCommand := manifest.Commands[0].GetCommand()
2292 expectedAidlFlag := "-Werror"
2293 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2294 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2295 }
2296}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002297
Jooyung Han07f70c02021-11-06 07:08:45 +09002298func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002299 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002300 for _, tc := range []struct {
2301 name string
2302 sdkVersion string
2303 variant string
2304 expected string
2305 }{
2306 {
2307 name: "default is current",
2308 sdkVersion: "",
2309 variant: "android_arm64_armv8-a_static",
2310 expected: "platform_apis",
2311 },
2312 {
2313 name: "use sdk_version",
2314 sdkVersion: `sdk_version: "29"`,
2315 variant: "android_arm64_armv8-a_static",
2316 expected: "platform_apis",
2317 },
2318 {
2319 name: "use sdk_version(sdk variant)",
2320 sdkVersion: `sdk_version: "29"`,
2321 variant: "android_arm64_armv8-a_sdk_static",
2322 expected: "29",
2323 },
2324 {
2325 name: "use min_sdk_version",
2326 sdkVersion: `min_sdk_version: "29"`,
2327 variant: "android_arm64_armv8-a_static",
2328 expected: "29",
2329 },
2330 } {
2331 t.Run(tc.name, func(t *testing.T) {
2332 ctx := testCc(t, `
2333 cc_library {
2334 name: "libfoo",
2335 stl: "none",
2336 srcs: ["a/Foo.aidl"],
2337 `+tc.sdkVersion+`
2338 }
2339 `)
2340 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002341 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002342 aidlCommand := manifest.Commands[0].GetCommand()
2343 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2344 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2345 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2346 }
2347 })
2348 }
2349}
2350
Vinh Tran09581952023-05-16 16:03:20 -04002351func TestInvalidAidlProp(t *testing.T) {
2352 t.Parallel()
2353
2354 testCases := []struct {
2355 description string
2356 bp string
2357 }{
2358 {
2359 description: "Invalid use of aidl.libs and aidl.include_dirs",
2360 bp: `
2361 cc_library {
2362 name: "foo",
2363 aidl: {
2364 libs: ["foo_aidl"],
2365 include_dirs: ["bar/include"],
2366 }
2367 }
2368 `,
2369 },
2370 {
2371 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2372 bp: `
2373 cc_library {
2374 name: "foo",
2375 aidl: {
2376 libs: ["foo_aidl"],
2377 local_include_dirs: ["include"],
2378 }
2379 }
2380 `,
2381 },
2382 }
2383
2384 for _, testCase := range testCases {
2385 t.Run(testCase.description, func(t *testing.T) {
2386 bp := `
2387 aidl_library {
2388 name: "foo_aidl",
2389 srcs: ["Foo.aidl"],
2390 } ` + testCase.bp
2391 android.GroupFixturePreparers(
2392 prepareForCcTest,
2393 aidl_library.PrepareForTestWithAidlLibrary.
2394 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2395 ).RunTestWithBp(t, bp)
2396 })
2397 }
2398}
2399
Jiyong Parka008fb02021-03-16 17:15:53 +09002400func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002401 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002402 ctx := testCc(t, `
2403 cc_library_shared {
2404 name: "libfoo",
2405 srcs: ["foo.c"],
2406 min_sdk_version: "29",
2407 }`)
2408
2409 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2410 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2411}
2412
Vinh Tranf1924742022-06-24 16:40:11 -04002413func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002414 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002415 bp := `
2416 cc_library_shared {
2417 name: "libfoo",
2418 srcs: ["foo.c"],
2419 min_sdk_version: "S",
2420 }
2421 `
2422 result := android.GroupFixturePreparers(
2423 prepareForCcTest,
2424 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2425 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2426 }),
2427 ).RunTestWithBp(t, bp)
2428 ctx := result.TestContext
2429 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2430 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2431}
2432
Paul Duffin3cb603e2021-02-19 13:57:10 +00002433func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002434 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002435
2436 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2437 // embedded newline characters alone.
2438 trimIndentingSpaces := func(s string) string {
2439 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2440 }
2441
2442 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2443 t.Helper()
2444 expected = trimIndentingSpaces(expected)
2445 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2446 if expected != actual {
2447 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2448 }
2449 }
2450
2451 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2452
2453 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2454 t.Helper()
Colin Cross5a377182023-12-14 14:46:23 -08002455 exported, _ := android.SingletonModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002456 name := module.Name()
2457
2458 for _, checker := range checkers {
2459 checker(t, name, exported)
2460 }
2461 }
2462
2463 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2464 return func(t *testing.T, name string, exported FlagExporterInfo) {
2465 t.Helper()
2466 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2467 }
2468 }
2469
2470 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2471 return func(t *testing.T, name string, exported FlagExporterInfo) {
2472 t.Helper()
2473 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2474 }
2475 }
2476
2477 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2478 return func(t *testing.T, name string, exported FlagExporterInfo) {
2479 t.Helper()
2480 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2481 }
2482 }
2483
2484 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2485 return func(t *testing.T, name string, exported FlagExporterInfo) {
2486 t.Helper()
2487 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2488 }
2489 }
2490
2491 genRuleModules := `
2492 genrule {
2493 name: "genrule_foo",
2494 cmd: "generate-foo",
2495 out: [
2496 "generated_headers/foo/generated_header.h",
2497 ],
2498 export_include_dirs: [
2499 "generated_headers",
2500 ],
2501 }
2502
2503 genrule {
2504 name: "genrule_bar",
2505 cmd: "generate-bar",
2506 out: [
2507 "generated_headers/bar/generated_header.h",
2508 ],
2509 export_include_dirs: [
2510 "generated_headers",
2511 ],
2512 }
2513 `
2514
2515 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2516 ctx := testCc(t, genRuleModules+`
2517 cc_library {
2518 name: "libfoo",
2519 srcs: ["foo.c"],
2520 export_include_dirs: ["foo/standard"],
2521 export_system_include_dirs: ["foo/system"],
2522 generated_headers: ["genrule_foo"],
2523 export_generated_headers: ["genrule_foo"],
2524 }
2525
2526 cc_library {
2527 name: "libbar",
2528 srcs: ["bar.c"],
2529 shared_libs: ["libfoo"],
2530 export_include_dirs: ["bar/standard"],
2531 export_system_include_dirs: ["bar/system"],
2532 generated_headers: ["genrule_bar"],
2533 export_generated_headers: ["genrule_bar"],
2534 }
2535 `)
2536 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2537 checkIncludeDirs(t, ctx, foo,
2538 expectedIncludeDirs(`
2539 foo/standard
2540 .intermediates/genrule_foo/gen/generated_headers
2541 `),
2542 expectedSystemIncludeDirs(`foo/system`),
2543 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2544 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2545 )
2546
2547 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2548 checkIncludeDirs(t, ctx, bar,
2549 expectedIncludeDirs(`
2550 bar/standard
2551 .intermediates/genrule_bar/gen/generated_headers
2552 `),
2553 expectedSystemIncludeDirs(`bar/system`),
2554 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2555 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2556 )
2557 })
2558
2559 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2560 ctx := testCc(t, genRuleModules+`
2561 cc_library {
2562 name: "libfoo",
2563 srcs: ["foo.c"],
2564 export_include_dirs: ["foo/standard"],
2565 export_system_include_dirs: ["foo/system"],
2566 generated_headers: ["genrule_foo"],
2567 export_generated_headers: ["genrule_foo"],
2568 }
2569
2570 cc_library {
2571 name: "libbar",
2572 srcs: ["bar.c"],
2573 whole_static_libs: ["libfoo"],
2574 export_include_dirs: ["bar/standard"],
2575 export_system_include_dirs: ["bar/system"],
2576 generated_headers: ["genrule_bar"],
2577 export_generated_headers: ["genrule_bar"],
2578 }
2579 `)
2580 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2581 checkIncludeDirs(t, ctx, foo,
2582 expectedIncludeDirs(`
2583 foo/standard
2584 .intermediates/genrule_foo/gen/generated_headers
2585 `),
2586 expectedSystemIncludeDirs(`foo/system`),
2587 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2588 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2589 )
2590
2591 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2592 checkIncludeDirs(t, ctx, bar,
2593 expectedIncludeDirs(`
2594 bar/standard
2595 foo/standard
2596 .intermediates/genrule_foo/gen/generated_headers
2597 .intermediates/genrule_bar/gen/generated_headers
2598 `),
2599 expectedSystemIncludeDirs(`
2600 bar/system
2601 foo/system
2602 `),
2603 expectedGeneratedHeaders(`
2604 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2605 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2606 `),
2607 expectedOrderOnlyDeps(`
2608 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2609 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2610 `),
2611 )
2612 })
2613
Paul Duffin3cb603e2021-02-19 13:57:10 +00002614 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002615 ctx := android.GroupFixturePreparers(
2616 prepareForCcTest,
2617 aidl_library.PrepareForTestWithAidlLibrary,
2618 ).RunTestWithBp(t, `
2619 aidl_library {
2620 name: "libfoo_aidl",
2621 srcs: ["x/y/Bar.aidl"],
2622 strip_import_prefix: "x",
2623 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002624 cc_library_shared {
2625 name: "libfoo",
2626 srcs: [
2627 "foo.c",
2628 "b.aidl",
2629 "a.proto",
2630 ],
2631 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002632 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002633 export_aidl_headers: true,
2634 }
2635 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002636 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002637 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2638 checkIncludeDirs(t, ctx, foo,
2639 expectedIncludeDirs(`
2640 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002641 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002642 `),
2643 expectedSystemIncludeDirs(``),
2644 expectedGeneratedHeaders(`
2645 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2646 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2647 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002648 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2649 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2650 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002651 `),
2652 expectedOrderOnlyDeps(`
2653 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2654 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2655 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002656 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2657 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2658 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002659 `),
2660 )
2661 })
2662
Paul Duffin3cb603e2021-02-19 13:57:10 +00002663 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2664 ctx := testCc(t, genRuleModules+`
2665 cc_library_shared {
2666 name: "libfoo",
2667 srcs: [
2668 "foo.c",
2669 "b.aidl",
2670 "a.proto",
2671 ],
2672 proto: {
2673 export_proto_headers: true,
2674 }
2675 }
2676 `)
2677 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2678 checkIncludeDirs(t, ctx, foo,
2679 expectedIncludeDirs(`
2680 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2681 `),
2682 expectedSystemIncludeDirs(``),
2683 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002684 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2685 `),
2686 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002687 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2688 `),
2689 )
2690 })
2691
Paul Duffin33056e82021-02-19 13:49:08 +00002692 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002693 ctx := testCc(t, genRuleModules+`
2694 cc_library_shared {
2695 name: "libfoo",
2696 srcs: [
2697 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002698 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002699 "b.aidl",
2700 "a.proto",
2701 ],
2702 }
2703 `)
2704 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2705 checkIncludeDirs(t, ctx, foo,
2706 expectedIncludeDirs(`
2707 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2708 `),
2709 expectedSystemIncludeDirs(``),
2710 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002711 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002712 `),
2713 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002714 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2715 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002716 `),
2717 )
2718 })
2719}
Colin Crossae628182021-06-14 16:52:28 -07002720
2721func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002722 t.Parallel()
Liz Kammer08572c62021-09-30 10:11:04 -04002723 baseExpectedFlags := []string{
2724 "${config.ArmThumbCflags}",
2725 "${config.ArmCflags}",
2726 "${config.CommonGlobalCflags}",
2727 "${config.DeviceGlobalCflags}",
2728 "${config.ExternalCflags}",
2729 "${config.ArmToolchainCflags}",
2730 "${config.ArmArmv7ANeonCflags}",
2731 "${config.ArmGenericCflags}",
2732 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002733 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002734 }
2735
2736 expectedIncludes := []string{
2737 "external/foo/android_arm_export_include_dirs",
2738 "external/foo/lib32_export_include_dirs",
2739 "external/foo/arm_export_include_dirs",
2740 "external/foo/android_export_include_dirs",
2741 "external/foo/linux_export_include_dirs",
2742 "external/foo/export_include_dirs",
2743 "external/foo/android_arm_local_include_dirs",
2744 "external/foo/lib32_local_include_dirs",
2745 "external/foo/arm_local_include_dirs",
2746 "external/foo/android_local_include_dirs",
2747 "external/foo/linux_local_include_dirs",
2748 "external/foo/local_include_dirs",
2749 "external/foo",
2750 "external/foo/libheader1",
2751 "external/foo/libheader2",
2752 "external/foo/libwhole1",
2753 "external/foo/libwhole2",
2754 "external/foo/libstatic1",
2755 "external/foo/libstatic2",
2756 "external/foo/libshared1",
2757 "external/foo/libshared2",
2758 "external/foo/liblinux",
2759 "external/foo/libandroid",
2760 "external/foo/libarm",
2761 "external/foo/lib32",
2762 "external/foo/libandroid_arm",
2763 "defaults/cc/common/ndk_libc++_shared",
Liz Kammer08572c62021-09-30 10:11:04 -04002764 }
2765
2766 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2767 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2768
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002769 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002770 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002771 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002772
2773 lastIncludes := []string{
2774 "out/soong/ndk/sysroot/usr/include",
2775 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
2776 }
2777
2778 combineSlices := func(slices ...[]string) []string {
2779 var ret []string
2780 for _, s := range slices {
2781 ret = append(ret, s...)
2782 }
2783 return ret
2784 }
2785
2786 testCases := []struct {
2787 name string
2788 src string
2789 expected []string
2790 }{
2791 {
2792 name: "c",
2793 src: "foo.c",
Yi Kong13beeed2023-07-15 03:09:00 +09002794 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002795 },
2796 {
2797 name: "cc",
2798 src: "foo.cc",
Yi Kong13beeed2023-07-15 03:09:00 +09002799 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002800 },
2801 {
2802 name: "assemble",
2803 src: "foo.s",
Yi Kong13beeed2023-07-15 03:09:00 +09002804 expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
Liz Kammer08572c62021-09-30 10:11:04 -04002805 },
2806 }
2807
2808 for _, tc := range testCases {
2809 t.Run(tc.name, func(t *testing.T) {
2810 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002811 cc_library {
2812 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002813 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002814 cflags: ["-std=candcpp"],
2815 conlyflags: ["-std=conly"],
2816 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002817 local_include_dirs: ["local_include_dirs"],
2818 export_include_dirs: ["export_include_dirs"],
2819 export_system_include_dirs: ["export_system_include_dirs"],
2820 static_libs: ["libstatic1", "libstatic2"],
2821 whole_static_libs: ["libwhole1", "libwhole2"],
2822 shared_libs: ["libshared1", "libshared2"],
2823 header_libs: ["libheader1", "libheader2"],
2824 target: {
2825 android: {
2826 shared_libs: ["libandroid"],
2827 local_include_dirs: ["android_local_include_dirs"],
2828 export_include_dirs: ["android_export_include_dirs"],
2829 },
2830 android_arm: {
2831 shared_libs: ["libandroid_arm"],
2832 local_include_dirs: ["android_arm_local_include_dirs"],
2833 export_include_dirs: ["android_arm_export_include_dirs"],
2834 },
2835 linux: {
2836 shared_libs: ["liblinux"],
2837 local_include_dirs: ["linux_local_include_dirs"],
2838 export_include_dirs: ["linux_export_include_dirs"],
2839 },
2840 },
2841 multilib: {
2842 lib32: {
2843 shared_libs: ["lib32"],
2844 local_include_dirs: ["lib32_local_include_dirs"],
2845 export_include_dirs: ["lib32_export_include_dirs"],
2846 },
2847 },
2848 arch: {
2849 arm: {
2850 shared_libs: ["libarm"],
2851 local_include_dirs: ["arm_local_include_dirs"],
2852 export_include_dirs: ["arm_export_include_dirs"],
2853 },
2854 },
2855 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002856 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002857 }
2858
2859 cc_library_headers {
2860 name: "libheader1",
2861 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002862 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002863 stl: "none",
2864 }
2865
2866 cc_library_headers {
2867 name: "libheader2",
2868 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002869 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002870 stl: "none",
2871 }
Liz Kammer08572c62021-09-30 10:11:04 -04002872 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002873
Liz Kammer08572c62021-09-30 10:11:04 -04002874 libs := []string{
2875 "libstatic1",
2876 "libstatic2",
2877 "libwhole1",
2878 "libwhole2",
2879 "libshared1",
2880 "libshared2",
2881 "libandroid",
2882 "libandroid_arm",
2883 "liblinux",
2884 "lib32",
2885 "libarm",
2886 }
Colin Crossae628182021-06-14 16:52:28 -07002887
Liz Kammer08572c62021-09-30 10:11:04 -04002888 for _, lib := range libs {
2889 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002890 cc_library {
2891 name: "%s",
2892 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002893 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002894 stl: "none",
2895 }
2896 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002897 }
2898
2899 ctx := android.GroupFixturePreparers(
2900 PrepareForIntegrationTestWithCc,
2901 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2902 ).RunTest(t)
Liz Kammer08572c62021-09-30 10:11:04 -04002903 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
2904
2905 var includes []string
2906 flags := strings.Split(cflags, " ")
2907 for _, flag := range flags {
2908 if strings.HasPrefix(flag, "-I") {
2909 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2910 } else if flag == "-isystem" {
2911 // skip isystem, include next
2912 } else if len(flag) > 0 {
2913 includes = append(includes, flag)
2914 }
2915 }
2916
2917 android.AssertArrayString(t, "includes", tc.expected, includes)
2918 })
Colin Crossae628182021-06-14 16:52:28 -07002919 }
2920
Colin Crossae628182021-06-14 16:52:28 -07002921}
Alixb5f6d9e2022-04-20 23:00:58 +00002922
zijunzhao933e3802023-01-12 07:26:20 +00002923func TestAddnoOverride64GlobalCflags(t *testing.T) {
2924 t.Parallel()
2925 ctx := testCc(t, `
2926 cc_library_shared {
2927 name: "libclient",
2928 srcs: ["foo.c"],
2929 shared_libs: ["libfoo#1"],
2930 }
2931
2932 cc_library_shared {
2933 name: "libfoo",
2934 srcs: ["foo.c"],
2935 shared_libs: ["libbar"],
2936 export_shared_lib_headers: ["libbar"],
2937 stubs: {
2938 symbol_file: "foo.map.txt",
2939 versions: ["1", "2", "3"],
2940 },
2941 }
2942
2943 cc_library_shared {
2944 name: "libbar",
2945 export_include_dirs: ["include/libbar"],
2946 srcs: ["foo.c"],
2947 }`)
2948
2949 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2950
2951 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2952 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2953 }
2954}
2955
Alixb5f6d9e2022-04-20 23:00:58 +00002956func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002957 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002958 tests := []struct {
2959 name string
2960 clang bool
2961 BuildBrokenClangProperty bool
2962 err string
2963 }{
2964 {
2965 name: "error when clang is set to false",
2966 clang: false,
2967 err: "is no longer supported",
2968 },
2969 {
2970 name: "error when clang is set to true",
2971 clang: true,
2972 err: "property is deprecated, see Changes.md",
2973 },
2974 {
2975 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2976 clang: true,
2977 BuildBrokenClangProperty: true,
2978 },
2979 }
2980
2981 for _, test := range tests {
2982 t.Run(test.name, func(t *testing.T) {
2983 bp := fmt.Sprintf(`
2984 cc_library {
2985 name: "foo",
2986 clang: %t,
2987 }`, test.clang)
2988
2989 if test.err == "" {
2990 android.GroupFixturePreparers(
2991 prepareForCcTest,
2992 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2993 if test.BuildBrokenClangProperty {
2994 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
2995 }
2996 }),
2997 ).RunTestWithBp(t, bp)
2998 } else {
2999 prepareForCcTest.
3000 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3001 RunTestWithBp(t, bp)
3002 }
3003 })
3004 }
3005}
Alix Espinoef47e542022-09-14 19:10:51 +00003006
3007func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003008 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003009 tests := []struct {
3010 name string
3011 clangAsFlags []string
3012 BuildBrokenClangAsFlags bool
3013 err string
3014 }{
3015 {
3016 name: "error when clang_asflags is set",
3017 clangAsFlags: []string{"-a", "-b"},
3018 err: "clang_asflags: property is deprecated",
3019 },
3020 {
3021 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3022 clangAsFlags: []string{"-a", "-b"},
3023 BuildBrokenClangAsFlags: true,
3024 },
3025 }
3026
3027 for _, test := range tests {
3028 t.Run(test.name, func(t *testing.T) {
3029 bp := fmt.Sprintf(`
3030 cc_library {
3031 name: "foo",
3032 clang_asflags: %s,
3033 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3034
3035 if test.err == "" {
3036 android.GroupFixturePreparers(
3037 prepareForCcTest,
3038 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3039 if test.BuildBrokenClangAsFlags {
3040 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3041 }
3042 }),
3043 ).RunTestWithBp(t, bp)
3044 } else {
3045 prepareForCcTest.
3046 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3047 RunTestWithBp(t, bp)
3048 }
3049 })
3050 }
3051}
3052
3053func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003054 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003055 tests := []struct {
3056 name string
3057 clangCFlags []string
3058 BuildBrokenClangCFlags bool
3059 err string
3060 }{
3061 {
3062 name: "error when clang_cflags is set",
3063 clangCFlags: []string{"-a", "-b"},
3064 err: "clang_cflags: property is deprecated",
3065 },
3066 {
3067 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3068 clangCFlags: []string{"-a", "-b"},
3069 BuildBrokenClangCFlags: true,
3070 },
3071 }
3072
3073 for _, test := range tests {
3074 t.Run(test.name, func(t *testing.T) {
3075 bp := fmt.Sprintf(`
3076 cc_library {
3077 name: "foo",
3078 clang_cflags: %s,
3079 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3080
3081 if test.err == "" {
3082 android.GroupFixturePreparers(
3083 prepareForCcTest,
3084 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3085 if test.BuildBrokenClangCFlags {
3086 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3087 }
3088 }),
3089 ).RunTestWithBp(t, bp)
3090 } else {
3091 prepareForCcTest.
3092 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3093 RunTestWithBp(t, bp)
3094 }
3095 })
3096 }
3097}
Wei Li5f5d2712023-12-11 15:40:29 -08003098
3099func TestStrippedAllOutputFile(t *testing.T) {
3100 t.Parallel()
3101 bp := `
3102 cc_library {
3103 name: "test_lib",
3104 srcs: ["test_lib.cpp"],
3105 dist: {
3106 targets: [ "dist_target" ],
3107 tag: "stripped_all",
3108 }
3109 }
3110 `
3111 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3112 ctx := testCcWithConfig(t, config)
mrziwangabdb2932024-06-18 12:43:41 -07003113 testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
3114 outputFile := testingModule.OutputFiles(t, "stripped_all")
Wei Li5f5d2712023-12-11 15:40:29 -08003115 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3116 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3117 return
3118 }
3119}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003120
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003121func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003122 t.Parallel()
3123
3124 bp := `
3125 cc_binary {
3126 name: "binfoo",
3127 srcs: ["binfoo.cc"],
3128 vendor_available: true,
3129 product_available: true,
3130 shared_libs: ["libbar"]
3131 }
3132 cc_library {
3133 name: "libbar",
3134 srcs: ["libbar.cc"],
3135 vendor_available: true,
3136 product_available: true,
3137 }
3138 `
3139
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003140 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003141
3142 hasDep := func(m android.Module, wantDep android.Module) bool {
3143 t.Helper()
3144 var found bool
3145 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3146 if dep == wantDep {
3147 found = true
3148 }
3149 })
3150 return found
3151 }
3152
3153 testDepWithVariant := func(imageVariant string) {
3154 imageVariantStr := ""
3155 if imageVariant != "core" {
3156 imageVariantStr = "_" + imageVariant
3157 }
3158 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3159 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3160 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3161 }
3162
3163 testDepWithVariant("core")
3164 testDepWithVariant("vendor")
3165 testDepWithVariant("product")
3166}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003167
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003168func TestVendorSdkVersion(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003169 t.Parallel()
3170
3171 bp := `
3172 cc_library {
3173 name: "libfoo",
3174 srcs: ["libfoo.cc"],
3175 vendor_available: true,
3176 }
3177
3178 cc_library {
3179 name: "libbar",
3180 srcs: ["libbar.cc"],
3181 vendor_available: true,
3182 min_sdk_version: "29",
3183 }
3184 `
3185
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003186 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003187 testSdkVersionFlag := func(module, version string) {
3188 flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3189 android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
3190 }
3191
3192 testSdkVersionFlag("libfoo", "10000")
3193 testSdkVersionFlag("libbar", "29")
3194
3195 ctx = android.GroupFixturePreparers(
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003196 prepareForCcTest,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003197 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3198 if variables.BuildFlags == nil {
3199 variables.BuildFlags = make(map[string]string)
3200 }
3201 variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
3202 }),
3203 ).RunTestWithBp(t, bp)
3204 testSdkVersionFlag("libfoo", "30")
3205 testSdkVersionFlag("libbar", "29")
3206}
kellyhungd62ea302024-05-19 21:16:07 +08003207
3208func TestClangVerify(t *testing.T) {
3209 t.Parallel()
3210
3211 ctx := testCc(t, `
3212 cc_library {
3213 name: "lib_no_clang_verify",
3214 srcs: ["libnocv.cc"],
3215 }
3216
3217 cc_library {
3218 name: "lib_clang_verify",
3219 srcs: ["libcv.cc"],
3220 clang_verify: true,
3221 }
3222 `)
3223
3224 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
3225
3226 cFlags_no_cv := module.Rule("cc").Args["cFlags"]
3227 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
3228 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
3229 }
3230
3231 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3232 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
3233 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
3234 }
3235}