• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 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
15package bp2build
16
17import (
18	"fmt"
19	"testing"
20
21	"android/soong/android"
22	"android/soong/cc"
23	"android/soong/genrule"
24)
25
26const (
27	// See cc/testing.go for more context
28	soongCcLibraryStaticPreamble = `
29cc_defaults {
30    name: "linux_bionic_supported",
31}`
32)
33
34func TestCcLibraryStaticLoadStatement(t *testing.T) {
35	testCases := []struct {
36		bazelTargets           BazelTargets
37		expectedLoadStatements string
38	}{
39		{
40			bazelTargets: BazelTargets{
41				BazelTarget{
42					name:      "cc_library_static_target",
43					ruleClass: "cc_library_static",
44					// NOTE: No bzlLoadLocation for native rules
45				},
46			},
47			expectedLoadStatements: ``,
48		},
49	}
50
51	for _, testCase := range testCases {
52		actual := testCase.bazelTargets.LoadStatements()
53		expected := testCase.expectedLoadStatements
54		if actual != expected {
55			t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
56		}
57	}
58}
59
60func registerCcLibraryStaticModuleTypes(ctx android.RegistrationContext) {
61	cc.RegisterCCBuildComponents(ctx)
62	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
63	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
64	// Required for system_shared_libs dependencies.
65	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
66}
67
68func runCcLibraryStaticTestCase(t *testing.T, tc Bp2buildTestCase) {
69	t.Helper()
70
71	(&tc).ModuleTypeUnderTest = "cc_library_static"
72	(&tc).ModuleTypeUnderTestFactory = cc.LibraryStaticFactory
73	RunBp2BuildTestCase(t, registerCcLibraryStaticModuleTypes, tc)
74}
75
76func TestCcLibraryStaticSimple(t *testing.T) {
77	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
78		Description: "cc_library_static test",
79		Filesystem: map[string]string{
80			// NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
81			"include_dir_1/include_dir_1_a.h": "",
82			"include_dir_1/include_dir_1_b.h": "",
83			"include_dir_2/include_dir_2_a.h": "",
84			"include_dir_2/include_dir_2_b.h": "",
85			// NOTE: local_include_dir headers *should not* appear in Bazel hdrs later (?)
86			"local_include_dir_1/local_include_dir_1_a.h": "",
87			"local_include_dir_1/local_include_dir_1_b.h": "",
88			"local_include_dir_2/local_include_dir_2_a.h": "",
89			"local_include_dir_2/local_include_dir_2_b.h": "",
90			// NOTE: export_include_dir headers *should* appear in Bazel hdrs later
91			"export_include_dir_1/export_include_dir_1_a.h": "",
92			"export_include_dir_1/export_include_dir_1_b.h": "",
93			"export_include_dir_2/export_include_dir_2_a.h": "",
94			"export_include_dir_2/export_include_dir_2_b.h": "",
95			// NOTE: Soong implicitly includes headers in the current directory
96			"implicit_include_1.h": "",
97			"implicit_include_2.h": "",
98		},
99		Blueprint: soongCcLibraryStaticPreamble + `
100cc_library_headers {
101    name: "header_lib_1",
102    export_include_dirs: ["header_lib_1"],
103    bazel_module: { bp2build_available: false },
104}
105
106cc_library_headers {
107    name: "header_lib_2",
108    export_include_dirs: ["header_lib_2"],
109    bazel_module: { bp2build_available: false },
110}
111
112cc_library_static {
113    name: "static_lib_1",
114    srcs: ["static_lib_1.cc"],
115    bazel_module: { bp2build_available: false },
116}
117
118cc_library_static {
119    name: "static_lib_2",
120    srcs: ["static_lib_2.cc"],
121    bazel_module: { bp2build_available: false },
122}
123
124cc_library_static {
125    name: "whole_static_lib_1",
126    srcs: ["whole_static_lib_1.cc"],
127    bazel_module: { bp2build_available: false },
128}
129
130cc_library_static {
131    name: "whole_static_lib_2",
132    srcs: ["whole_static_lib_2.cc"],
133    bazel_module: { bp2build_available: false },
134}
135
136cc_library_static {
137    name: "foo_static",
138    srcs: [
139        "foo_static1.cc",
140        "foo_static2.cc",
141    ],
142    cflags: [
143        "-Dflag1",
144        "-Dflag2"
145    ],
146    static_libs: [
147        "static_lib_1",
148        "static_lib_2"
149    ],
150    whole_static_libs: [
151        "whole_static_lib_1",
152        "whole_static_lib_2"
153    ],
154    include_dirs: [
155        "include_dir_1",
156        "include_dir_2",
157    ],
158    local_include_dirs: [
159        "local_include_dir_1",
160        "local_include_dir_2",
161    ],
162    export_include_dirs: [
163        "export_include_dir_1",
164        "export_include_dir_2"
165    ],
166    header_libs: [
167        "header_lib_1",
168        "header_lib_2"
169    ],
170    sdk_version: "current",
171    min_sdk_version: "29",
172
173    // TODO: Also support export_header_lib_headers
174}`,
175		ExpectedBazelTargets: []string{
176			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
177				"absolute_includes": `[
178        "include_dir_1",
179        "include_dir_2",
180    ]`,
181				"copts": `[
182        "-Dflag1",
183        "-Dflag2",
184    ]`,
185				"export_includes": `[
186        "export_include_dir_1",
187        "export_include_dir_2",
188    ]`,
189				"implementation_deps": `[
190        ":header_lib_1",
191        ":header_lib_2",
192        ":static_lib_1",
193        ":static_lib_2",
194    ]`,
195				"local_includes": `[
196        "local_include_dir_1",
197        "local_include_dir_2",
198        ".",
199    ]`,
200				"srcs": `[
201        "foo_static1.cc",
202        "foo_static2.cc",
203    ]`,
204				"whole_archive_deps": `[
205        ":whole_static_lib_1",
206        ":whole_static_lib_2",
207    ]`,
208				"sdk_version":     `"current"`,
209				"min_sdk_version": `"29"`,
210			}),
211		},
212	})
213}
214
215func TestCcLibraryStaticSubpackage(t *testing.T) {
216	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
217		Description: "cc_library_static subpackage test",
218		Filesystem: map[string]string{
219			// subpackage with subdirectory
220			"subpackage/Android.bp":                         "",
221			"subpackage/subpackage_header.h":                "",
222			"subpackage/subdirectory/subdirectory_header.h": "",
223			// subsubpackage with subdirectory
224			"subpackage/subsubpackage/Android.bp":                         "",
225			"subpackage/subsubpackage/subsubpackage_header.h":             "",
226			"subpackage/subsubpackage/subdirectory/subdirectory_header.h": "",
227			// subsubsubpackage with subdirectory
228			"subpackage/subsubpackage/subsubsubpackage/Android.bp":                         "",
229			"subpackage/subsubpackage/subsubsubpackage/subsubsubpackage_header.h":          "",
230			"subpackage/subsubpackage/subsubsubpackage/subdirectory/subdirectory_header.h": "",
231		},
232		Blueprint: soongCcLibraryStaticPreamble + `
233cc_library_static {
234    name: "foo_static",
235    srcs: [],
236    include_dirs: [
237        "subpackage",
238    ],
239}`,
240		ExpectedBazelTargets: []string{
241			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
242				"absolute_includes": `["subpackage"]`,
243				"local_includes":    `["."]`,
244			}),
245		},
246	})
247}
248
249func TestCcLibraryStaticExportIncludeDir(t *testing.T) {
250	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
251		Description: "cc_library_static export include dir",
252		Filesystem: map[string]string{
253			// subpackage with subdirectory
254			"subpackage/Android.bp":                         "",
255			"subpackage/subpackage_header.h":                "",
256			"subpackage/subdirectory/subdirectory_header.h": "",
257		},
258		Blueprint: soongCcLibraryStaticPreamble + `
259cc_library_static {
260    name: "foo_static",
261    export_include_dirs: ["subpackage"],
262    include_build_directory: false,
263}`,
264		ExpectedBazelTargets: []string{
265			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
266				"export_includes": `["subpackage"]`,
267			}),
268		},
269	})
270}
271
272func TestCcLibraryStaticExportSystemIncludeDir(t *testing.T) {
273	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
274		Description: "cc_library_static export system include dir",
275		Filesystem: map[string]string{
276			// subpackage with subdirectory
277			"subpackage/Android.bp":                         "",
278			"subpackage/subpackage_header.h":                "",
279			"subpackage/subdirectory/subdirectory_header.h": "",
280		},
281		Blueprint: soongCcLibraryStaticPreamble + `
282cc_library_static {
283    name: "foo_static",
284    export_system_include_dirs: ["subpackage"],
285    include_build_directory: false,
286}`,
287		ExpectedBazelTargets: []string{
288			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
289				"export_system_includes": `["subpackage"]`,
290			}),
291		},
292	})
293}
294
295func TestCcLibraryStaticManyIncludeDirs(t *testing.T) {
296	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
297		Description: "cc_library_static include_dirs, local_include_dirs, export_include_dirs (b/183742505)",
298		Dir:         "subpackage",
299		Filesystem: map[string]string{
300			// subpackage with subdirectory
301			"subpackage/Android.bp": `
302cc_library_static {
303    name: "foo_static",
304    // include_dirs are workspace/root relative
305    include_dirs: [
306        "subpackage/subsubpackage",
307        "subpackage2",
308        "subpackage3/subsubpackage"
309    ],
310    local_include_dirs: ["subsubpackage2"], // module dir relative
311    export_include_dirs: ["./exported_subsubpackage"], // module dir relative
312    include_build_directory: true,
313    bazel_module: { bp2build_available: true },
314}`,
315			"subpackage/subsubpackage/header.h":          "",
316			"subpackage/subsubpackage2/header.h":         "",
317			"subpackage/exported_subsubpackage/header.h": "",
318			"subpackage2/header.h":                       "",
319			"subpackage3/subsubpackage/header.h":         "",
320		},
321		Blueprint: soongCcLibraryStaticPreamble,
322		ExpectedBazelTargets: []string{
323			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
324				"absolute_includes": `[
325        "subpackage/subsubpackage",
326        "subpackage2",
327        "subpackage3/subsubpackage",
328    ]`,
329				"export_includes": `["./exported_subsubpackage"]`,
330				"local_includes": `[
331        "subsubpackage2",
332        ".",
333    ]`,
334			})},
335	})
336}
337
338func TestCcLibraryStaticIncludeBuildDirectoryDisabled(t *testing.T) {
339	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
340		Description: "cc_library_static include_build_directory disabled",
341		Filesystem: map[string]string{
342			// subpackage with subdirectory
343			"subpackage/Android.bp":                         "",
344			"subpackage/subpackage_header.h":                "",
345			"subpackage/subdirectory/subdirectory_header.h": "",
346		},
347		Blueprint: soongCcLibraryStaticPreamble + `
348cc_library_static {
349    name: "foo_static",
350    include_dirs: ["subpackage"], // still used, but local_include_dirs is recommended
351    local_include_dirs: ["subpackage2"],
352    include_build_directory: false,
353}`,
354		ExpectedBazelTargets: []string{
355			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
356				"absolute_includes": `["subpackage"]`,
357				"local_includes":    `["subpackage2"]`,
358			}),
359		},
360	})
361}
362
363func TestCcLibraryStaticIncludeBuildDirectoryEnabled(t *testing.T) {
364	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
365		Description: "cc_library_static include_build_directory enabled",
366		Filesystem: map[string]string{
367			// subpackage with subdirectory
368			"subpackage/Android.bp":                         "",
369			"subpackage/subpackage_header.h":                "",
370			"subpackage2/Android.bp":                        "",
371			"subpackage2/subpackage2_header.h":              "",
372			"subpackage/subdirectory/subdirectory_header.h": "",
373		},
374		Blueprint: soongCcLibraryStaticPreamble + `
375cc_library_static {
376    name: "foo_static",
377    include_dirs: ["subpackage"], // still used, but local_include_dirs is recommended
378    local_include_dirs: ["subpackage2"],
379    include_build_directory: true,
380}`,
381		ExpectedBazelTargets: []string{
382			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
383				"absolute_includes": `["subpackage"]`,
384				"local_includes": `[
385        "subpackage2",
386        ".",
387    ]`,
388			}),
389		},
390	})
391}
392
393func TestCcLibraryStaticArchSpecificStaticLib(t *testing.T) {
394	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
395		Description: "cc_library_static arch-specific static_libs",
396		Filesystem:  map[string]string{},
397		Blueprint: soongCcLibraryStaticPreamble + `
398cc_library_static {
399    name: "static_dep",
400    bazel_module: { bp2build_available: false },
401}
402cc_library_static {
403    name: "static_dep2",
404    bazel_module: { bp2build_available: false },
405}
406cc_library_static {
407    name: "foo_static",
408    arch: { arm64: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
409    include_build_directory: false,
410}`,
411		ExpectedBazelTargets: []string{
412			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
413				"implementation_deps": `select({
414        "//build/bazel/platforms/arch:arm64": [":static_dep"],
415        "//conditions:default": [],
416    })`,
417				"whole_archive_deps": `select({
418        "//build/bazel/platforms/arch:arm64": [":static_dep2"],
419        "//conditions:default": [],
420    })`,
421			}),
422		},
423	})
424}
425
426func TestCcLibraryStaticOsSpecificStaticLib(t *testing.T) {
427	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
428		Description: "cc_library_static os-specific static_libs",
429		Filesystem:  map[string]string{},
430		Blueprint: soongCcLibraryStaticPreamble + `
431cc_library_static {
432    name: "static_dep",
433    bazel_module: { bp2build_available: false },
434}
435cc_library_static {
436    name: "static_dep2",
437    bazel_module: { bp2build_available: false },
438}
439cc_library_static {
440    name: "foo_static",
441    target: { android: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
442    include_build_directory: false,
443}`,
444		ExpectedBazelTargets: []string{
445			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
446				"implementation_deps": `select({
447        "//build/bazel/platforms/os:android": [":static_dep"],
448        "//conditions:default": [],
449    })`,
450				"whole_archive_deps": `select({
451        "//build/bazel/platforms/os:android": [":static_dep2"],
452        "//conditions:default": [],
453    })`,
454			}),
455		},
456	})
457}
458
459func TestCcLibraryStaticBaseArchOsSpecificStaticLib(t *testing.T) {
460	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
461		Description: "cc_library_static base, arch and os-specific static_libs",
462		Filesystem:  map[string]string{},
463		Blueprint: soongCcLibraryStaticPreamble + `
464cc_library_static {
465    name: "static_dep",
466    bazel_module: { bp2build_available: false },
467}
468cc_library_static {
469    name: "static_dep2",
470    bazel_module: { bp2build_available: false },
471}
472cc_library_static {
473    name: "static_dep3",
474    bazel_module: { bp2build_available: false },
475}
476cc_library_static {
477    name: "static_dep4",
478    bazel_module: { bp2build_available: false },
479}
480cc_library_static {
481    name: "foo_static",
482    static_libs: ["static_dep"],
483    whole_static_libs: ["static_dep2"],
484    target: { android: { static_libs: ["static_dep3"] } },
485    arch: { arm64: { static_libs: ["static_dep4"] } },
486    include_build_directory: false,
487}`,
488		ExpectedBazelTargets: []string{
489			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
490				"implementation_deps": `[":static_dep"] + select({
491        "//build/bazel/platforms/arch:arm64": [":static_dep4"],
492        "//conditions:default": [],
493    }) + select({
494        "//build/bazel/platforms/os:android": [":static_dep3"],
495        "//conditions:default": [],
496    })`,
497				"whole_archive_deps": `[":static_dep2"]`,
498			}),
499		},
500	})
501}
502
503func TestCcLibraryStaticSimpleExcludeSrcs(t *testing.T) {
504	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
505		Description: "cc_library_static simple exclude_srcs",
506		Filesystem: map[string]string{
507			"common.c":       "",
508			"foo-a.c":        "",
509			"foo-excluded.c": "",
510		},
511		Blueprint: soongCcLibraryStaticPreamble + `
512cc_library_static {
513    name: "foo_static",
514    srcs: ["common.c", "foo-*.c"],
515    exclude_srcs: ["foo-excluded.c"],
516    include_build_directory: false,
517}`,
518		ExpectedBazelTargets: []string{
519			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
520				"srcs_c": `[
521        "common.c",
522        "foo-a.c",
523    ]`,
524			}),
525		},
526	})
527}
528
529func TestCcLibraryStaticOneArchSrcs(t *testing.T) {
530	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
531		Description: "cc_library_static one arch specific srcs",
532		Filesystem: map[string]string{
533			"common.c":  "",
534			"foo-arm.c": "",
535		},
536		Blueprint: soongCcLibraryStaticPreamble + `
537cc_library_static {
538    name: "foo_static",
539    srcs: ["common.c"],
540    arch: { arm: { srcs: ["foo-arm.c"] } },
541    include_build_directory: false,
542}`,
543		ExpectedBazelTargets: []string{
544			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
545				"srcs_c": `["common.c"] + select({
546        "//build/bazel/platforms/arch:arm": ["foo-arm.c"],
547        "//conditions:default": [],
548    })`,
549			}),
550		},
551	})
552}
553
554func TestCcLibraryStaticOneArchSrcsExcludeSrcs(t *testing.T) {
555	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
556		Description: "cc_library_static one arch specific srcs and exclude_srcs",
557		Filesystem: map[string]string{
558			"common.c":           "",
559			"for-arm.c":          "",
560			"not-for-arm.c":      "",
561			"not-for-anything.c": "",
562		},
563		Blueprint: soongCcLibraryStaticPreamble + `
564cc_library_static {
565    name: "foo_static",
566    srcs: ["common.c", "not-for-*.c"],
567    exclude_srcs: ["not-for-anything.c"],
568    arch: {
569        arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
570    },
571    include_build_directory: false,
572}`,
573		ExpectedBazelTargets: []string{
574			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
575				"srcs_c": `["common.c"] + select({
576        "//build/bazel/platforms/arch:arm": ["for-arm.c"],
577        "//conditions:default": ["not-for-arm.c"],
578    })`,
579			}),
580		},
581	})
582}
583
584func TestCcLibraryStaticTwoArchExcludeSrcs(t *testing.T) {
585	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
586		Description: "cc_library_static arch specific exclude_srcs for 2 architectures",
587		Filesystem: map[string]string{
588			"common.c":      "",
589			"for-arm.c":     "",
590			"for-x86.c":     "",
591			"not-for-arm.c": "",
592			"not-for-x86.c": "",
593		},
594		Blueprint: soongCcLibraryStaticPreamble + `
595cc_library_static {
596    name: "foo_static",
597    srcs: ["common.c", "not-for-*.c"],
598    exclude_srcs: ["not-for-everything.c"],
599    arch: {
600        arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
601        x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
602    },
603    include_build_directory: false,
604} `,
605		ExpectedBazelTargets: []string{
606			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
607				"srcs_c": `["common.c"] + select({
608        "//build/bazel/platforms/arch:arm": [
609            "not-for-x86.c",
610            "for-arm.c",
611        ],
612        "//build/bazel/platforms/arch:x86": [
613            "not-for-arm.c",
614            "for-x86.c",
615        ],
616        "//conditions:default": [
617            "not-for-arm.c",
618            "not-for-x86.c",
619        ],
620    })`,
621			}),
622		},
623	})
624}
625
626func TestCcLibraryStaticFourArchExcludeSrcs(t *testing.T) {
627	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
628		Description: "cc_library_static arch specific exclude_srcs for 4 architectures",
629		Filesystem: map[string]string{
630			"common.c":             "",
631			"for-arm.c":            "",
632			"for-arm64.c":          "",
633			"for-x86.c":            "",
634			"for-x86_64.c":         "",
635			"not-for-arm.c":        "",
636			"not-for-arm64.c":      "",
637			"not-for-x86.c":        "",
638			"not-for-x86_64.c":     "",
639			"not-for-everything.c": "",
640		},
641		Blueprint: soongCcLibraryStaticPreamble + `
642cc_library_static {
643    name: "foo_static",
644    srcs: ["common.c", "not-for-*.c"],
645    exclude_srcs: ["not-for-everything.c"],
646    arch: {
647        arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
648        arm64: { srcs: ["for-arm64.c"], exclude_srcs: ["not-for-arm64.c"] },
649        x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
650        x86_64: { srcs: ["for-x86_64.c"], exclude_srcs: ["not-for-x86_64.c"] },
651  },
652    include_build_directory: false,
653} `,
654		ExpectedBazelTargets: []string{
655			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
656				"srcs_c": `["common.c"] + select({
657        "//build/bazel/platforms/arch:arm": [
658            "not-for-arm64.c",
659            "not-for-x86.c",
660            "not-for-x86_64.c",
661            "for-arm.c",
662        ],
663        "//build/bazel/platforms/arch:arm64": [
664            "not-for-arm.c",
665            "not-for-x86.c",
666            "not-for-x86_64.c",
667            "for-arm64.c",
668        ],
669        "//build/bazel/platforms/arch:x86": [
670            "not-for-arm.c",
671            "not-for-arm64.c",
672            "not-for-x86_64.c",
673            "for-x86.c",
674        ],
675        "//build/bazel/platforms/arch:x86_64": [
676            "not-for-arm.c",
677            "not-for-arm64.c",
678            "not-for-x86.c",
679            "for-x86_64.c",
680        ],
681        "//conditions:default": [
682            "not-for-arm.c",
683            "not-for-arm64.c",
684            "not-for-x86.c",
685            "not-for-x86_64.c",
686        ],
687    })`,
688			}),
689		},
690	})
691}
692
693func TestCcLibraryStaticOneArchEmpty(t *testing.T) {
694	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
695		Description: "cc_library_static one arch empty",
696		Filesystem: map[string]string{
697			"common.cc":       "",
698			"foo-no-arm.cc":   "",
699			"foo-excluded.cc": "",
700		},
701		Blueprint: soongCcLibraryStaticPreamble + `
702cc_library_static {
703    name: "foo_static",
704    srcs: ["common.cc", "foo-*.cc"],
705    exclude_srcs: ["foo-excluded.cc"],
706    arch: {
707        arm: { exclude_srcs: ["foo-no-arm.cc"] },
708    },
709    include_build_directory: false,
710}`,
711		ExpectedBazelTargets: []string{
712			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
713				"srcs": `["common.cc"] + select({
714        "//build/bazel/platforms/arch:arm": [],
715        "//conditions:default": ["foo-no-arm.cc"],
716    })`,
717			}),
718		},
719	})
720}
721
722func TestCcLibraryStaticOneArchEmptyOtherSet(t *testing.T) {
723	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
724		Description: "cc_library_static one arch empty other set",
725		Filesystem: map[string]string{
726			"common.cc":       "",
727			"foo-no-arm.cc":   "",
728			"x86-only.cc":     "",
729			"foo-excluded.cc": "",
730		},
731		Blueprint: soongCcLibraryStaticPreamble + `
732cc_library_static {
733    name: "foo_static",
734    srcs: ["common.cc", "foo-*.cc"],
735    exclude_srcs: ["foo-excluded.cc"],
736    arch: {
737        arm: { exclude_srcs: ["foo-no-arm.cc"] },
738        x86: { srcs: ["x86-only.cc"] },
739    },
740    include_build_directory: false,
741}`,
742		ExpectedBazelTargets: []string{
743			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
744				"srcs": `["common.cc"] + select({
745        "//build/bazel/platforms/arch:arm": [],
746        "//build/bazel/platforms/arch:x86": [
747            "foo-no-arm.cc",
748            "x86-only.cc",
749        ],
750        "//conditions:default": ["foo-no-arm.cc"],
751    })`,
752			}),
753		},
754	})
755}
756
757func TestCcLibraryStaticMultipleDepSameName(t *testing.T) {
758	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
759		Description: "cc_library_static multiple dep same name panic",
760		Filesystem:  map[string]string{},
761		Blueprint: soongCcLibraryStaticPreamble + `
762cc_library_static {
763    name: "static_dep",
764    bazel_module: { bp2build_available: false },
765}
766cc_library_static {
767    name: "foo_static",
768    static_libs: ["static_dep", "static_dep"],
769    include_build_directory: false,
770}`,
771		ExpectedBazelTargets: []string{
772			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
773				"implementation_deps": `[":static_dep"]`,
774			}),
775		},
776	})
777}
778
779func TestCcLibraryStaticOneMultilibSrcsExcludeSrcs(t *testing.T) {
780	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
781		Description: "cc_library_static 1 multilib srcs and exclude_srcs",
782		Filesystem: map[string]string{
783			"common.c":        "",
784			"for-lib32.c":     "",
785			"not-for-lib32.c": "",
786		},
787		Blueprint: soongCcLibraryStaticPreamble + `
788cc_library_static {
789    name: "foo_static",
790    srcs: ["common.c", "not-for-*.c"],
791    multilib: {
792        lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
793    },
794    include_build_directory: false,
795} `,
796		ExpectedBazelTargets: []string{
797			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
798				"srcs_c": `["common.c"] + select({
799        "//build/bazel/platforms/arch:arm": ["for-lib32.c"],
800        "//build/bazel/platforms/arch:x86": ["for-lib32.c"],
801        "//conditions:default": ["not-for-lib32.c"],
802    })`,
803			}),
804		},
805	})
806}
807
808func TestCcLibraryStaticTwoMultilibSrcsExcludeSrcs(t *testing.T) {
809	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
810		Description: "cc_library_static 2 multilib srcs and exclude_srcs",
811		Filesystem: map[string]string{
812			"common.c":        "",
813			"for-lib32.c":     "",
814			"for-lib64.c":     "",
815			"not-for-lib32.c": "",
816			"not-for-lib64.c": "",
817		},
818		Blueprint: soongCcLibraryStaticPreamble + `
819cc_library_static {
820    name: "foo_static",
821    srcs: ["common.c", "not-for-*.c"],
822    multilib: {
823        lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
824        lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
825    },
826    include_build_directory: false,
827} `,
828		ExpectedBazelTargets: []string{
829			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
830				"srcs_c": `["common.c"] + select({
831        "//build/bazel/platforms/arch:arm": [
832            "not-for-lib64.c",
833            "for-lib32.c",
834        ],
835        "//build/bazel/platforms/arch:arm64": [
836            "not-for-lib32.c",
837            "for-lib64.c",
838        ],
839        "//build/bazel/platforms/arch:riscv64": [
840            "not-for-lib32.c",
841            "for-lib64.c",
842        ],
843        "//build/bazel/platforms/arch:x86": [
844            "not-for-lib64.c",
845            "for-lib32.c",
846        ],
847        "//build/bazel/platforms/arch:x86_64": [
848            "not-for-lib32.c",
849            "for-lib64.c",
850        ],
851        "//conditions:default": [
852            "not-for-lib32.c",
853            "not-for-lib64.c",
854        ],
855    })`,
856			}),
857		},
858	})
859}
860
861func TestCcLibrarySTaticArchMultilibSrcsExcludeSrcs(t *testing.T) {
862	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
863		Description: "cc_library_static arch and multilib srcs and exclude_srcs",
864		Filesystem: map[string]string{
865			"common.c":             "",
866			"for-arm.c":            "",
867			"for-arm64.c":          "",
868			"for-x86.c":            "",
869			"for-x86_64.c":         "",
870			"for-lib32.c":          "",
871			"for-lib64.c":          "",
872			"not-for-arm.c":        "",
873			"not-for-arm64.c":      "",
874			"not-for-riscv64.c":    "",
875			"not-for-x86.c":        "",
876			"not-for-x86_64.c":     "",
877			"not-for-lib32.c":      "",
878			"not-for-lib64.c":      "",
879			"not-for-everything.c": "",
880		},
881		Blueprint: soongCcLibraryStaticPreamble + `
882cc_library_static {
883   name: "foo_static",
884   srcs: ["common.c", "not-for-*.c"],
885   exclude_srcs: ["not-for-everything.c"],
886   arch: {
887       arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
888       arm64: { srcs: ["for-arm64.c"], exclude_srcs: ["not-for-arm64.c"] },
889       riscv64: { srcs: ["for-riscv64.c"], exclude_srcs: ["not-for-riscv64.c"] },
890       x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
891       x86_64: { srcs: ["for-x86_64.c"], exclude_srcs: ["not-for-x86_64.c"] },
892   },
893   multilib: {
894       lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
895       lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
896   },
897    include_build_directory: false,
898}`,
899		ExpectedBazelTargets: []string{
900			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
901				"srcs_c": `["common.c"] + select({
902        "//build/bazel/platforms/arch:arm": [
903            "not-for-arm64.c",
904            "not-for-lib64.c",
905            "not-for-riscv64.c",
906            "not-for-x86.c",
907            "not-for-x86_64.c",
908            "for-arm.c",
909            "for-lib32.c",
910        ],
911        "//build/bazel/platforms/arch:arm64": [
912            "not-for-arm.c",
913            "not-for-lib32.c",
914            "not-for-riscv64.c",
915            "not-for-x86.c",
916            "not-for-x86_64.c",
917            "for-arm64.c",
918            "for-lib64.c",
919        ],
920        "//build/bazel/platforms/arch:riscv64": [
921            "not-for-arm.c",
922            "not-for-arm64.c",
923            "not-for-lib32.c",
924            "not-for-x86.c",
925            "not-for-x86_64.c",
926            "for-riscv64.c",
927            "for-lib64.c",
928        ],
929        "//build/bazel/platforms/arch:x86": [
930            "not-for-arm.c",
931            "not-for-arm64.c",
932            "not-for-lib64.c",
933            "not-for-riscv64.c",
934            "not-for-x86_64.c",
935            "for-x86.c",
936            "for-lib32.c",
937        ],
938        "//build/bazel/platforms/arch:x86_64": [
939            "not-for-arm.c",
940            "not-for-arm64.c",
941            "not-for-lib32.c",
942            "not-for-riscv64.c",
943            "not-for-x86.c",
944            "for-x86_64.c",
945            "for-lib64.c",
946        ],
947        "//conditions:default": [
948            "not-for-arm.c",
949            "not-for-arm64.c",
950            "not-for-lib32.c",
951            "not-for-lib64.c",
952            "not-for-riscv64.c",
953            "not-for-x86.c",
954            "not-for-x86_64.c",
955        ],
956    })`,
957			}),
958		},
959	})
960}
961
962func TestCcLibraryStaticGeneratedHeadersAllPartitions(t *testing.T) {
963	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
964		Blueprint: soongCcLibraryStaticPreamble + `
965genrule {
966    name: "generated_hdr",
967    cmd: "nothing to see here",
968    bazel_module: { bp2build_available: false },
969}
970
971genrule {
972    name: "export_generated_hdr",
973    cmd: "nothing to see here",
974    bazel_module: { bp2build_available: false },
975}
976
977cc_library_static {
978    name: "foo_static",
979    srcs: ["cpp_src.cpp", "as_src.S", "c_src.c"],
980    generated_headers: ["generated_hdr", "export_generated_hdr"],
981    export_generated_headers: ["export_generated_hdr"],
982    include_build_directory: false,
983}`,
984		ExpectedBazelTargets: []string{
985			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
986				"export_includes": `["."]`,
987				"local_includes":  `["."]`,
988				"hdrs":            `[":export_generated_hdr"]`,
989				"srcs": `[
990        "cpp_src.cpp",
991        ":generated_hdr",
992    ]`,
993				"srcs_as": `[
994        "as_src.S",
995        ":generated_hdr",
996    ]`,
997				"srcs_c": `[
998        "c_src.c",
999        ":generated_hdr",
1000    ]`,
1001			}),
1002		},
1003	})
1004}
1005
1006// generated_headers has "variant_prepend" tag. In bp2build output,
1007// variant info(select) should go before general info.
1008func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
1009	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1010		Description: "cc_library_static arch srcs/exclude_srcs with generated files",
1011		Filesystem: map[string]string{
1012			"common.cpp":             "",
1013			"for-x86.cpp":            "",
1014			"not-for-x86.cpp":        "",
1015			"not-for-everything.cpp": "",
1016			"dep/Android.bp": simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg") +
1017				simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg") +
1018				simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg_x86") +
1019				simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_x86") +
1020				simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_android"),
1021		},
1022		Blueprint: soongCcLibraryStaticPreamble +
1023			simpleModuleDoNotConvertBp2build("genrule", "generated_src") +
1024			simpleModuleDoNotConvertBp2build("genrule", "generated_src_not_x86") +
1025			simpleModuleDoNotConvertBp2build("genrule", "generated_src_android") +
1026			simpleModuleDoNotConvertBp2build("genrule", "generated_hdr") + `
1027cc_library_static {
1028    name: "foo_static",
1029    srcs: ["common.cpp", "not-for-*.cpp"],
1030    exclude_srcs: ["not-for-everything.cpp"],
1031    generated_sources: ["generated_src", "generated_src_other_pkg", "generated_src_not_x86"],
1032    generated_headers: ["generated_hdr", "generated_hdr_other_pkg"],
1033    export_generated_headers: ["generated_hdr_other_pkg"],
1034    arch: {
1035        x86: {
1036          srcs: ["for-x86.cpp"],
1037          exclude_srcs: ["not-for-x86.cpp"],
1038          generated_headers: ["generated_hdr_other_pkg_x86"],
1039          exclude_generated_sources: ["generated_src_not_x86"],
1040    export_generated_headers: ["generated_hdr_other_pkg_x86"],
1041        },
1042    },
1043    target: {
1044        android: {
1045            generated_sources: ["generated_src_android"],
1046            generated_headers: ["generated_hdr_other_pkg_android"],
1047    export_generated_headers: ["generated_hdr_other_pkg_android"],
1048        },
1049    },
1050
1051    include_build_directory: false,
1052}
1053`,
1054		ExpectedBazelTargets: []string{
1055			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
1056				"srcs": `[
1057        "common.cpp",
1058        ":generated_src",
1059        "//dep:generated_src_other_pkg",
1060        ":generated_hdr",
1061    ] + select({
1062        "//build/bazel/platforms/arch:x86": ["for-x86.cpp"],
1063        "//conditions:default": [
1064            "not-for-x86.cpp",
1065            ":generated_src_not_x86",
1066        ],
1067    }) + select({
1068        "//build/bazel/platforms/os:android": [":generated_src_android"],
1069        "//conditions:default": [],
1070    })`,
1071				"hdrs": `select({
1072        "//build/bazel/platforms/os:android": ["//dep:generated_hdr_other_pkg_android"],
1073        "//conditions:default": [],
1074    }) + select({
1075        "//build/bazel/platforms/arch:x86": ["//dep:generated_hdr_other_pkg_x86"],
1076        "//conditions:default": [],
1077    }) + ["//dep:generated_hdr_other_pkg"]`,
1078				"local_includes":           `["."]`,
1079				"export_absolute_includes": `["dep"]`,
1080			}),
1081		},
1082	})
1083}
1084
1085func TestCcLibraryStaticGetTargetProperties(t *testing.T) {
1086	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1087
1088		Description: "cc_library_static complex GetTargetProperties",
1089		Blueprint: soongCcLibraryStaticPreamble + `
1090cc_library_static {
1091    name: "foo_static",
1092    target: {
1093        android: {
1094            srcs: ["android_src.c"],
1095        },
1096        android_arm: {
1097            srcs: ["android_arm_src.c"],
1098        },
1099        android_arm64: {
1100            srcs: ["android_arm64_src.c"],
1101        },
1102        android_x86: {
1103            srcs: ["android_x86_src.c"],
1104        },
1105        android_x86_64: {
1106            srcs: ["android_x86_64_src.c"],
1107        },
1108        linux_bionic_arm64: {
1109            srcs: ["linux_bionic_arm64_src.c"],
1110        },
1111        linux_bionic_x86_64: {
1112            srcs: ["linux_bionic_x86_64_src.c"],
1113        },
1114    },
1115    include_build_directory: false,
1116}`,
1117		ExpectedBazelTargets: []string{
1118			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
1119				"srcs_c": `select({
1120        "//build/bazel/platforms/os:android": ["android_src.c"],
1121        "//conditions:default": [],
1122    }) + select({
1123        "//build/bazel/platforms/os_arch:android_arm": ["android_arm_src.c"],
1124        "//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"],
1125        "//build/bazel/platforms/os_arch:android_x86": ["android_x86_src.c"],
1126        "//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_src.c"],
1127        "//build/bazel/platforms/os_arch:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
1128        "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
1129        "//conditions:default": [],
1130    })`,
1131			}),
1132		},
1133	})
1134}
1135
1136func TestCcLibraryStaticProductVariableSelects(t *testing.T) {
1137	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1138		Description: "cc_library_static product variable selects",
1139		Blueprint: soongCcLibraryStaticPreamble + `
1140cc_library_static {
1141    name: "foo_static",
1142    srcs: ["common.c"],
1143    product_variables: {
1144      malloc_not_svelte: {
1145        cflags: ["-Wmalloc_not_svelte"],
1146      },
1147      malloc_zero_contents: {
1148        cflags: ["-Wmalloc_zero_contents"],
1149      },
1150      binder32bit: {
1151        cflags: ["-Wbinder32bit"],
1152      },
1153    },
1154    include_build_directory: false,
1155} `,
1156		ExpectedBazelTargets: []string{
1157			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
1158				"copts": `select({
1159        "//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
1160        "//conditions:default": [],
1161    }) + select({
1162        "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
1163        "//conditions:default": [],
1164    }) + select({
1165        "//build/bazel/product_variables:malloc_zero_contents": ["-Wmalloc_zero_contents"],
1166        "//conditions:default": [],
1167    })`,
1168				"srcs_c": `["common.c"]`,
1169			}),
1170		},
1171	})
1172}
1173
1174func TestCcLibraryStaticProductVariableArchSpecificSelects(t *testing.T) {
1175	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1176		Description: "cc_library_static arch-specific product variable selects",
1177		Filesystem:  map[string]string{},
1178		Blueprint: soongCcLibraryStaticPreamble + `
1179cc_library_static {
1180    name: "foo_static",
1181    srcs: ["common.c"],
1182    product_variables: {
1183      malloc_not_svelte: {
1184        cflags: ["-Wmalloc_not_svelte"],
1185      },
1186    },
1187    arch: {
1188        arm64: {
1189            product_variables: {
1190                malloc_not_svelte: {
1191                    cflags: ["-Warm64_malloc_not_svelte"],
1192                },
1193            },
1194        },
1195    },
1196    multilib: {
1197        lib32: {
1198            product_variables: {
1199                malloc_not_svelte: {
1200                    cflags: ["-Wlib32_malloc_not_svelte"],
1201                },
1202            },
1203        },
1204    },
1205    target: {
1206        android: {
1207            product_variables: {
1208                malloc_not_svelte: {
1209                    cflags: ["-Wandroid_malloc_not_svelte"],
1210                },
1211            },
1212        }
1213    },
1214    include_build_directory: false,
1215} `,
1216		ExpectedBazelTargets: []string{
1217			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
1218				"copts": `select({
1219        "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
1220        "//conditions:default": [],
1221    }) + select({
1222        "//build/bazel/product_variables:malloc_not_svelte-android": ["-Wandroid_malloc_not_svelte"],
1223        "//conditions:default": [],
1224    }) + select({
1225        "//build/bazel/product_variables:malloc_not_svelte-arm": ["-Wlib32_malloc_not_svelte"],
1226        "//conditions:default": [],
1227    }) + select({
1228        "//build/bazel/product_variables:malloc_not_svelte-arm64": ["-Warm64_malloc_not_svelte"],
1229        "//conditions:default": [],
1230    }) + select({
1231        "//build/bazel/product_variables:malloc_not_svelte-x86": ["-Wlib32_malloc_not_svelte"],
1232        "//conditions:default": [],
1233    })`,
1234				"srcs_c": `["common.c"]`,
1235			}),
1236		},
1237	})
1238}
1239
1240func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) {
1241	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1242		Description: "cc_library_static product variable string replacement",
1243		Filesystem:  map[string]string{},
1244		Blueprint: soongCcLibraryStaticPreamble + `
1245cc_library_static {
1246    name: "foo_static",
1247    srcs: ["common.S"],
1248    product_variables: {
1249      platform_sdk_version: {
1250          asflags: ["-DPLATFORM_SDK_VERSION=%d"],
1251      },
1252    },
1253    include_build_directory: false,
1254} `,
1255		ExpectedBazelTargets: []string{
1256			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
1257				"asflags": `select({
1258        "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
1259        "//conditions:default": [],
1260    })`,
1261				"srcs_as": `["common.S"]`,
1262			}),
1263		},
1264	})
1265}
1266
1267func TestStaticLibrary_SystemSharedLibsRootEmpty(t *testing.T) {
1268	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1269		Description: "cc_library_static system_shared_lib empty root",
1270		Blueprint: soongCcLibraryStaticPreamble + `
1271cc_library_static {
1272    name: "root_empty",
1273    system_shared_libs: [],
1274    include_build_directory: false,
1275}
1276`,
1277		ExpectedBazelTargets: []string{
1278			MakeBazelTarget("cc_library_static", "root_empty", AttrNameToString{
1279				"system_dynamic_deps": `[]`,
1280			}),
1281		},
1282	})
1283}
1284
1285func TestStaticLibrary_SystemSharedLibsStaticEmpty(t *testing.T) {
1286	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1287		Description: "cc_library_static system_shared_lib empty static default",
1288		Blueprint: soongCcLibraryStaticPreamble + `
1289cc_defaults {
1290    name: "static_empty_defaults",
1291    static: {
1292        system_shared_libs: [],
1293    },
1294    include_build_directory: false,
1295}
1296cc_library_static {
1297    name: "static_empty",
1298    defaults: ["static_empty_defaults"],
1299}
1300`,
1301		ExpectedBazelTargets: []string{
1302			MakeBazelTarget("cc_library_static", "static_empty", AttrNameToString{
1303				"system_dynamic_deps": `[]`,
1304			}),
1305		},
1306	})
1307}
1308
1309func TestStaticLibrary_SystemSharedLibsBionicEmpty(t *testing.T) {
1310	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1311		Description: "cc_library_static system_shared_lib empty for bionic variant",
1312		Blueprint: soongCcLibraryStaticPreamble + `
1313cc_library {
1314		name: "libc_musl",
1315		bazel_module: { bp2build_available: false },
1316}
1317
1318cc_library_static {
1319    name: "target_bionic_empty",
1320    target: {
1321        bionic: {
1322            system_shared_libs: [],
1323        },
1324    },
1325    include_build_directory: false,
1326}
1327`,
1328		ExpectedBazelTargets: []string{
1329			MakeBazelTarget("cc_library_static", "target_bionic_empty", AttrNameToString{
1330				"system_dynamic_deps": `select({
1331        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1332        "//conditions:default": [],
1333    })`,
1334			}),
1335		},
1336	})
1337}
1338
1339func TestStaticLibrary_SystemSharedLibsLinuxBionicEmpty(t *testing.T) {
1340	// Note that this behavior is technically incorrect (it's a simplification).
1341	// The correct behavior would be if bp2build wrote `system_dynamic_deps = []`
1342	// only for linux_bionic, but `android` had `["libc", "libdl", "libm"].
1343	// b/195791252 tracks the fix.
1344	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1345		Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
1346		Blueprint: soongCcLibraryStaticPreamble + `
1347cc_library {
1348		name: "libc_musl",
1349		bazel_module: { bp2build_available: false },
1350}
1351
1352cc_library_static {
1353    name: "target_linux_bionic_empty",
1354    target: {
1355        linux_bionic: {
1356            system_shared_libs: [],
1357        },
1358    },
1359    include_build_directory: false,
1360}
1361`,
1362		ExpectedBazelTargets: []string{
1363			MakeBazelTarget("cc_library_static", "target_linux_bionic_empty", AttrNameToString{
1364				"system_dynamic_deps": `select({
1365        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1366        "//conditions:default": [],
1367    })`,
1368			}),
1369		},
1370	})
1371}
1372
1373func TestStaticLibrary_SystemSharedLibsMuslEmpty(t *testing.T) {
1374	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1375		Description: "cc_library_static system_shared_lib empty for musl variant",
1376		Blueprint: soongCcLibraryStaticPreamble + `
1377cc_library {
1378		name: "libc_musl",
1379		bazel_module: { bp2build_available: false },
1380}
1381
1382cc_library_static {
1383    name: "target_musl_empty",
1384    target: {
1385        musl: {
1386            system_shared_libs: [],
1387        },
1388    },
1389    include_build_directory: false,
1390}
1391`,
1392		ExpectedBazelTargets: []string{
1393			MakeBazelTarget("cc_library_static", "target_musl_empty", AttrNameToString{
1394				"system_dynamic_deps": `[]`,
1395			}),
1396		},
1397	})
1398}
1399
1400func TestStaticLibrary_SystemSharedLibsLinuxMuslEmpty(t *testing.T) {
1401	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1402		Description: "cc_library_static system_shared_lib empty for linux_musl variant",
1403		Blueprint: soongCcLibraryStaticPreamble + `
1404cc_library {
1405		name: "libc_musl",
1406		bazel_module: { bp2build_available: false },
1407}
1408
1409cc_library_static {
1410    name: "target_linux_musl_empty",
1411    target: {
1412        linux_musl: {
1413            system_shared_libs: [],
1414        },
1415    },
1416    include_build_directory: false,
1417}
1418`,
1419		ExpectedBazelTargets: []string{
1420			MakeBazelTarget("cc_library_static", "target_linux_musl_empty", AttrNameToString{
1421				"system_dynamic_deps": `[]`,
1422			}),
1423		},
1424	})
1425}
1426
1427func TestStaticLibrary_SystemSharedLibsBionic(t *testing.T) {
1428	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1429		Description: "cc_library_static system_shared_libs set for bionic variant",
1430		Blueprint: soongCcLibraryStaticPreamble +
1431			simpleModuleDoNotConvertBp2build("cc_library", "libc") + `
1432cc_library {
1433	name: "libc_musl",
1434	bazel_module: { bp2build_available: false },
1435}
1436
1437cc_library_static {
1438    name: "target_bionic",
1439    target: {
1440        bionic: {
1441            system_shared_libs: ["libc"],
1442        },
1443    },
1444    include_build_directory: false,
1445}
1446`,
1447		ExpectedBazelTargets: []string{
1448			MakeBazelTarget("cc_library_static", "target_bionic", AttrNameToString{
1449				"system_dynamic_deps": `select({
1450        "//build/bazel/platforms/os:android": [":libc"],
1451        "//build/bazel/platforms/os:linux_bionic": [":libc"],
1452        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1453        "//conditions:default": [],
1454    })`,
1455			}),
1456		},
1457	})
1458}
1459
1460func TestStaticLibrary_SystemSharedLibsLinuxRootAndLinuxBionic(t *testing.T) {
1461	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1462		Description: "cc_library_static system_shared_libs set for root and linux_bionic variant",
1463		Blueprint: soongCcLibraryStaticPreamble +
1464			simpleModuleDoNotConvertBp2build("cc_library", "libc") +
1465			simpleModuleDoNotConvertBp2build("cc_library", "libm") + `
1466cc_library {
1467	name: "libc_musl",
1468	bazel_module: { bp2build_available: false },
1469}
1470
1471cc_library_static {
1472    name: "target_linux_bionic",
1473    system_shared_libs: ["libc"],
1474    target: {
1475        linux_bionic: {
1476            system_shared_libs: ["libm"],
1477        },
1478    },
1479    include_build_directory: false,
1480}
1481`,
1482		ExpectedBazelTargets: []string{
1483			MakeBazelTarget("cc_library_static", "target_linux_bionic", AttrNameToString{
1484				"system_dynamic_deps": `[":libc"] + select({
1485        "//build/bazel/platforms/os:linux_bionic": [":libm"],
1486        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1487        "//conditions:default": [],
1488    })`,
1489			}),
1490		},
1491	})
1492}
1493
1494func TestCcLibrarystatic_SystemSharedLibUsedAsDep(t *testing.T) {
1495	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1496		Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
1497		Blueprint: soongCcLibraryStaticPreamble +
1498			simpleModuleDoNotConvertBp2build("cc_library", "libc") + `
1499
1500cc_library {
1501    name: "libm",
1502    stubs: {
1503        symbol_file: "libm.map.txt",
1504        versions: ["current"],
1505    },
1506    bazel_module: { bp2build_available: false },
1507}
1508
1509cc_library_static {
1510    name: "used_in_bionic_oses",
1511    target: {
1512        android: {
1513            shared_libs: ["libc"],
1514        },
1515        linux_bionic: {
1516            shared_libs: ["libc"],
1517        },
1518    },
1519    include_build_directory: false,
1520    apex_available: ["foo"],
1521}
1522
1523cc_library_static {
1524    name: "all",
1525    shared_libs: ["libc"],
1526    include_build_directory: false,
1527    apex_available: ["foo"],
1528}
1529
1530cc_library_static {
1531    name: "keep_for_empty_system_shared_libs",
1532    shared_libs: ["libc"],
1533    system_shared_libs: [],
1534    include_build_directory: false,
1535    apex_available: ["foo"],
1536}
1537
1538cc_library_static {
1539    name: "used_with_stubs",
1540    shared_libs: ["libm"],
1541    include_build_directory: false,
1542    apex_available: ["foo"],
1543}
1544
1545cc_library_static {
1546    name: "keep_with_stubs",
1547    shared_libs: ["libm"],
1548    system_shared_libs: [],
1549    include_build_directory: false,
1550    apex_available: ["foo"],
1551}
1552`,
1553		ExpectedBazelTargets: []string{
1554			MakeBazelTarget("cc_library_static", "all", AttrNameToString{
1555				"tags": `["apex_available=foo"]`,
1556			}),
1557			MakeBazelTarget("cc_library_static", "keep_for_empty_system_shared_libs", AttrNameToString{
1558				"implementation_dynamic_deps": `[":libc"]`,
1559				"system_dynamic_deps":         `[]`,
1560				"tags":                        `["apex_available=foo"]`,
1561			}),
1562			MakeBazelTarget("cc_library_static", "keep_with_stubs", AttrNameToString{
1563				"implementation_dynamic_deps": `select({
1564        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:libm"],
1565        "//conditions:default": [":libm"],
1566    })`,
1567				"system_dynamic_deps": `[]`,
1568				"tags":                `["apex_available=foo"]`,
1569			}),
1570			MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{
1571				"tags": `["apex_available=foo"]`,
1572			}),
1573			MakeBazelTarget("cc_library_static", "used_with_stubs", AttrNameToString{
1574				"tags": `["apex_available=foo"]`,
1575			}),
1576		},
1577	})
1578}
1579
1580func TestCcLibraryStaticProto(t *testing.T) {
1581	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1582		Blueprint: soongCcProtoPreamble + `cc_library_static {
1583	name: "foo",
1584	srcs: ["foo.proto"],
1585	proto: {
1586		export_proto_headers: true,
1587	},
1588	include_build_directory: false,
1589}`,
1590		ExpectedBazelTargets: []string{
1591			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
1592				"srcs": `["foo.proto"]`,
1593			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
1594				"deps": `[":foo_proto"]`,
1595			}), MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1596				"deps":               `[":libprotobuf-cpp-lite"]`,
1597				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
1598			}),
1599		},
1600	})
1601}
1602
1603func TestCcLibraryStaticUseVersionLib(t *testing.T) {
1604	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1605		Filesystem: map[string]string{
1606			soongCcVersionLibBpPath: soongCcVersionLibBp,
1607		},
1608		Blueprint: soongCcProtoPreamble + `cc_library_static {
1609	name: "foo",
1610	use_version_lib: true,
1611	static_libs: ["libbuildversion"],
1612	include_build_directory: false,
1613}`,
1614		ExpectedBazelTargets: []string{
1615			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1616				"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
1617			}),
1618		},
1619	})
1620}
1621
1622func TestCcLibraryStaticUseVersionLibHasDep(t *testing.T) {
1623	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1624		Filesystem: map[string]string{
1625			soongCcVersionLibBpPath: soongCcVersionLibBp,
1626		},
1627		Blueprint: soongCcProtoPreamble + `cc_library_static {
1628	name: "foo",
1629	use_version_lib: true,
1630	whole_static_libs: ["libbuildversion"],
1631	include_build_directory: false,
1632}`,
1633		ExpectedBazelTargets: []string{
1634			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1635				"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
1636			}),
1637		},
1638	})
1639}
1640
1641func TestCcLibraryStaticStdInFlags(t *testing.T) {
1642	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1643		Blueprint: soongCcProtoPreamble + `cc_library_static {
1644	name: "foo",
1645	cflags: ["-std=candcpp"],
1646	conlyflags: ["-std=conly"],
1647	cppflags: ["-std=cpp"],
1648	include_build_directory: false,
1649}`,
1650		ExpectedBazelTargets: []string{
1651			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1652				"conlyflags": `["-std=conly"]`,
1653				"cppflags":   `["-std=cpp"]`,
1654			}),
1655		},
1656	})
1657}
1658
1659func TestCcLibraryStaticStl(t *testing.T) {
1660	testCases := []struct {
1661		desc string
1662		prop string
1663		attr AttrNameToString
1664	}{
1665		{
1666			desc: "c++_shared deduped to libc++",
1667			prop: `stl: "c++_shared",`,
1668			attr: AttrNameToString{
1669				"stl": `"libc++"`,
1670			},
1671		},
1672		{
1673			desc: "libc++ to libc++",
1674			prop: `stl: "libc++",`,
1675			attr: AttrNameToString{
1676				"stl": `"libc++"`,
1677			},
1678		},
1679		{
1680			desc: "c++_static to libc++_static",
1681			prop: `stl: "c++_static",`,
1682			attr: AttrNameToString{
1683				"stl": `"libc++_static"`,
1684			},
1685		},
1686		{
1687			desc: "libc++_static to libc++_static",
1688			prop: `stl: "libc++_static",`,
1689			attr: AttrNameToString{
1690				"stl": `"libc++_static"`,
1691			},
1692		},
1693		{
1694			desc: "system to system",
1695			prop: `stl: "system",`,
1696			attr: AttrNameToString{
1697				"stl": `"system"`,
1698			},
1699		},
1700		{
1701			desc: "none to none",
1702			prop: `stl: "none",`,
1703			attr: AttrNameToString{
1704				"stl": `"none"`,
1705			},
1706		},
1707		{
1708			desc: "empty to empty",
1709			attr: AttrNameToString{},
1710		},
1711	}
1712	for _, tc := range testCases {
1713		t.Run(tc.desc, func(*testing.T) {
1714			runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1715				Blueprint: fmt.Sprintf(`cc_library_static {
1716	name: "foo",
1717	include_build_directory: false,
1718	%s
1719}`, tc.prop),
1720				ExpectedBazelTargets: []string{
1721					MakeBazelTarget("cc_library_static", "foo", tc.attr),
1722				},
1723			})
1724		})
1725	}
1726}
1727
1728func TestCCLibraryStaticRuntimeDeps(t *testing.T) {
1729	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1730		Blueprint: `cc_library_shared {
1731	name: "bar",
1732}
1733
1734cc_library_static {
1735  name: "foo",
1736  runtime_libs: ["foo"],
1737}`,
1738		ExpectedBazelTargets: []string{
1739			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
1740				"local_includes": `["."]`,
1741			}),
1742			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1743				"runtime_deps":   `[":foo"]`,
1744				"local_includes": `["."]`,
1745			}),
1746		},
1747	})
1748}
1749
1750func TestCcLibraryStaticWithSyspropSrcs(t *testing.T) {
1751	runCcLibraryTestCase(t, Bp2buildTestCase{
1752		Description: "cc_library_static with sysprop sources",
1753		Blueprint: `
1754cc_library_static {
1755	name: "foo",
1756	srcs: [
1757		"bar.sysprop",
1758		"baz.sysprop",
1759		"blah.cpp",
1760	],
1761	min_sdk_version: "5",
1762}`,
1763		ExpectedBazelTargets: []string{
1764			MakeBazelTarget("sysprop_library", "foo_sysprop_library", AttrNameToString{
1765				"srcs": `[
1766        "bar.sysprop",
1767        "baz.sysprop",
1768    ]`,
1769			}),
1770			MakeBazelTarget("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
1771				"dep":             `":foo_sysprop_library"`,
1772				"min_sdk_version": `"5"`,
1773			}),
1774			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1775				"srcs":               `["blah.cpp"]`,
1776				"local_includes":     `["."]`,
1777				"min_sdk_version":    `"5"`,
1778				"whole_archive_deps": `[":foo_cc_sysprop_library_static"]`,
1779			}),
1780		},
1781	})
1782}
1783
1784func TestCcLibraryStaticWithSyspropSrcsSomeConfigs(t *testing.T) {
1785	runCcLibraryTestCase(t, Bp2buildTestCase{
1786		Description: "cc_library_static with sysprop sources in some configs but not others",
1787		Blueprint: `
1788cc_library_static {
1789	name: "foo",
1790	srcs: [
1791		"blah.cpp",
1792	],
1793	target: {
1794		android: {
1795			srcs: ["bar.sysprop"],
1796		},
1797	},
1798	min_sdk_version: "5",
1799}`,
1800		ExpectedBazelTargets: []string{
1801			MakeBazelTarget("sysprop_library", "foo_sysprop_library", AttrNameToString{
1802				"srcs": `select({
1803        "//build/bazel/platforms/os:android": ["bar.sysprop"],
1804        "//conditions:default": [],
1805    })`,
1806			}),
1807			MakeBazelTarget("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
1808				"dep":             `":foo_sysprop_library"`,
1809				"min_sdk_version": `"5"`,
1810			}),
1811			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1812				"srcs":            `["blah.cpp"]`,
1813				"local_includes":  `["."]`,
1814				"min_sdk_version": `"5"`,
1815				"whole_archive_deps": `select({
1816        "//build/bazel/platforms/os:android": [":foo_cc_sysprop_library_static"],
1817        "//conditions:default": [],
1818    })`,
1819			}),
1820		},
1821	})
1822}
1823
1824func TestCcLibraryStaticWithIntegerOverflowProperty(t *testing.T) {
1825	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1826		Description: "cc_library_static has correct features when integer_overflow property is provided",
1827		Blueprint: `
1828cc_library_static {
1829		name: "foo",
1830		sanitize: {
1831				integer_overflow: true,
1832		},
1833}
1834`,
1835		ExpectedBazelTargets: []string{
1836			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1837				"features":       `["ubsan_integer_overflow"]`,
1838				"local_includes": `["."]`,
1839			}),
1840		},
1841	})
1842}
1843
1844func TestCcLibraryStaticWithMiscUndefinedProperty(t *testing.T) {
1845	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1846		Description: "cc_library_static has correct features when misc_undefined property is provided",
1847		Blueprint: `
1848cc_library_static {
1849		name: "foo",
1850		sanitize: {
1851				misc_undefined: ["undefined", "nullability"],
1852		},
1853}
1854`,
1855		ExpectedBazelTargets: []string{
1856			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1857				"features": `[
1858        "ubsan_undefined",
1859        "ubsan_nullability",
1860    ]`,
1861				"local_includes": `["."]`,
1862			}),
1863		},
1864	})
1865}
1866
1867func TestCcLibraryStaticWithUBSanPropertiesArchSpecific(t *testing.T) {
1868	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1869		Description: "cc_library_static has correct feature select when UBSan props are specified in arch specific blocks",
1870		Blueprint: `
1871cc_library_static {
1872		name: "foo",
1873		sanitize: {
1874				misc_undefined: ["undefined", "nullability"],
1875		},
1876		target: {
1877				android: {
1878						sanitize: {
1879								misc_undefined: ["alignment"],
1880						},
1881				},
1882				linux_glibc: {
1883						sanitize: {
1884								integer_overflow: true,
1885						},
1886				},
1887		},
1888}
1889`,
1890		ExpectedBazelTargets: []string{
1891			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1892				"features": `[
1893        "ubsan_undefined",
1894        "ubsan_nullability",
1895    ] + select({
1896        "//build/bazel/platforms/os:android": ["ubsan_alignment"],
1897        "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"],
1898        "//conditions:default": [],
1899    })`,
1900				"local_includes": `["."]`,
1901			}),
1902		},
1903	})
1904}
1905
1906func TestCcLibraryStaticWithThinLto(t *testing.T) {
1907	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1908		Description: "cc_library_static has correct features when thin lto is enabled",
1909		Blueprint: `
1910cc_library_static {
1911	name: "foo",
1912	lto: {
1913		thin: true,
1914	},
1915}
1916`,
1917		ExpectedBazelTargets: []string{
1918			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1919				"features":       `["android_thin_lto"]`,
1920				"local_includes": `["."]`,
1921			}),
1922		},
1923	})
1924}
1925
1926func TestCcLibraryStaticWithLtoNever(t *testing.T) {
1927	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1928		Description: "cc_library_static has correct features when thin lto is enabled",
1929		Blueprint: `
1930cc_library_static {
1931	name: "foo",
1932	lto: {
1933		never: true,
1934	},
1935}
1936`,
1937		ExpectedBazelTargets: []string{
1938			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1939				"features":       `["-android_thin_lto"]`,
1940				"local_includes": `["."]`,
1941			}),
1942		},
1943	})
1944}
1945
1946func TestCcLibraryStaticWithThinLtoArchSpecific(t *testing.T) {
1947	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1948		Description: "cc_library_static has correct features when LTO differs across arch and os variants",
1949		Blueprint: `
1950cc_library_static {
1951	name: "foo",
1952	target: {
1953		android: {
1954			lto: {
1955				thin: true,
1956			},
1957		},
1958	},
1959	arch: {
1960		riscv64: {
1961			lto: {
1962				thin: false,
1963			},
1964		},
1965	},
1966}`,
1967		ExpectedBazelTargets: []string{
1968			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
1969				"local_includes": `["."]`,
1970				"features": `select({
1971        "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
1972        "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
1973        "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
1974        "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
1975        "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
1976        "//conditions:default": [],
1977    })`}),
1978		},
1979	})
1980}
1981
1982func TestCcLibraryStaticWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
1983	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
1984		Description: "cc_library_static has correct features when LTO disabled by default but enabled on a particular variant",
1985		Blueprint: `
1986cc_library_static {
1987	name: "foo",
1988	lto: {
1989		never: true,
1990	},
1991	target: {
1992		android: {
1993			lto: {
1994				thin: true,
1995				never: false,
1996			},
1997		},
1998	},
1999}`,
2000		ExpectedBazelTargets: []string{
2001			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
2002				"local_includes": `["."]`,
2003				"features": `select({
2004        "//build/bazel/platforms/os:android": ["android_thin_lto"],
2005        "//conditions:default": ["-android_thin_lto"],
2006    })`,
2007			}),
2008		},
2009	})
2010}
2011
2012func TestCcLibraryStaticWithThinLtoAndWholeProgramVtables(t *testing.T) {
2013	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
2014		Description: "cc_library_static has correct features when thin lto is enabled with whole_program_vtables",
2015		Blueprint: `
2016cc_library_static {
2017	name: "foo",
2018	lto: {
2019		thin: true,
2020	},
2021	whole_program_vtables: true,
2022}
2023`,
2024		ExpectedBazelTargets: []string{
2025			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
2026				"features": `[
2027        "android_thin_lto",
2028        "android_thin_lto_whole_program_vtables",
2029    ]`,
2030				"local_includes": `["."]`,
2031			}),
2032		},
2033	})
2034}
2035