• 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)
24
25const (
26	// See cc/testing.go for more context
27	soongCcLibraryPreamble = `
28cc_defaults {
29    name: "linux_bionic_supported",
30}
31`
32
33	soongCcVersionLibBpPath = "build/soong/cc/libbuildversion/Android.bp"
34	soongCcVersionLibBp     = `
35cc_library_static {
36	name: "libbuildversion",
37	bazel_module: { bp2build_available: false },
38}
39`
40
41	soongCcProtoLibraries = `
42cc_library {
43	name: "libprotobuf-cpp-lite",
44	bazel_module: { bp2build_available: false },
45}
46
47cc_library {
48	name: "libprotobuf-cpp-full",
49	bazel_module: { bp2build_available: false },
50}`
51
52	soongCcProtoPreamble = soongCcLibraryPreamble + soongCcProtoLibraries
53)
54
55func runCcLibraryTestCase(t *testing.T, tc Bp2buildTestCase) {
56	t.Helper()
57	RunBp2BuildTestCase(t, registerCcLibraryModuleTypes, tc)
58}
59
60func registerCcLibraryModuleTypes(ctx android.RegistrationContext) {
61	cc.RegisterCCBuildComponents(ctx)
62	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
63	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
64	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
65	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
66}
67
68func TestCcLibrarySimple(t *testing.T) {
69	runCcLibraryTestCase(t, Bp2buildTestCase{
70		Description:                "cc_library - simple example",
71		ModuleTypeUnderTest:        "cc_library",
72		ModuleTypeUnderTestFactory: cc.LibraryFactory,
73		Filesystem: map[string]string{
74			soongCcVersionLibBpPath: soongCcVersionLibBp,
75			"android.cpp":           "",
76			"bionic.cpp":            "",
77			"darwin.cpp":            "",
78			// Refer to cc.headerExts for the supported header extensions in Soong.
79			"header.h":         "",
80			"header.hh":        "",
81			"header.hpp":       "",
82			"header.hxx":       "",
83			"header.h++":       "",
84			"header.inl":       "",
85			"header.inc":       "",
86			"header.ipp":       "",
87			"header.h.generic": "",
88			"impl.cpp":         "",
89			"linux.cpp":        "",
90			"x86.cpp":          "",
91			"x86_64.cpp":       "",
92			"foo-dir/a.h":      "",
93		},
94		Blueprint: soongCcLibraryPreamble +
95			simpleModuleDoNotConvertBp2build("cc_library_headers", "some-headers") + `
96cc_library {
97    name: "foo-lib",
98    srcs: ["impl.cpp"],
99    cflags: ["-Wall"],
100    header_libs: ["some-headers"],
101    export_include_dirs: ["foo-dir"],
102    ldflags: ["-Wl,--exclude-libs=bar.a"],
103    arch: {
104        x86: {
105            ldflags: ["-Wl,--exclude-libs=baz.a"],
106            srcs: ["x86.cpp"],
107        },
108        x86_64: {
109            ldflags: ["-Wl,--exclude-libs=qux.a"],
110            srcs: ["x86_64.cpp"],
111        },
112    },
113    target: {
114        android: {
115            srcs: ["android.cpp"],
116        },
117        linux_glibc: {
118            srcs: ["linux.cpp"],
119        },
120        darwin: {
121            srcs: ["darwin.cpp"],
122        },
123        bionic: {
124          srcs: ["bionic.cpp"]
125        },
126    },
127    include_build_directory: false,
128    sdk_version: "current",
129    min_sdk_version: "29",
130    use_version_lib: true,
131}
132`,
133		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
134			"copts":               `["-Wall"]`,
135			"export_includes":     `["foo-dir"]`,
136			"implementation_deps": `[":some-headers"]`,
137			"linkopts": `["-Wl,--exclude-libs=bar.a"] + select({
138        "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
139        "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
140        "//conditions:default": [],
141    })`,
142			"srcs": `["impl.cpp"] + select({
143        "//build/bazel/platforms/arch:x86": ["x86.cpp"],
144        "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
145        "//conditions:default": [],
146    }) + select({
147        "//build/bazel/platforms/os:android": [
148            "bionic.cpp",
149            "android.cpp",
150        ],
151        "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
152        "//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"],
153        "//build/bazel/platforms/os:linux_glibc": ["linux.cpp"],
154        "//conditions:default": [],
155    })`,
156			"sdk_version":                       `"current"`,
157			"min_sdk_version":                   `"29"`,
158			"use_version_lib":                   `True`,
159			"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
160		}),
161	})
162}
163
164func TestCcLibraryTrimmedLdAndroid(t *testing.T) {
165	runCcLibraryTestCase(t, Bp2buildTestCase{
166		Description:                "cc_library - trimmed example of //bionic/linker:ld-android",
167		ModuleTypeUnderTest:        "cc_library",
168		ModuleTypeUnderTestFactory: cc.LibraryFactory,
169		Filesystem: map[string]string{
170			"ld-android.cpp":           "",
171			"linked_list.h":            "",
172			"linker.h":                 "",
173			"linker_block_allocator.h": "",
174			"linker_cfi.h":             "",
175		},
176		Blueprint: soongCcLibraryPreamble +
177			simpleModuleDoNotConvertBp2build("cc_library_headers", "libc_headers") + `
178cc_library {
179    name: "fake-ld-android",
180    srcs: ["ld_android.cpp"],
181    cflags: [
182        "-Wall",
183        "-Wextra",
184        "-Wunused",
185        "-Werror",
186    ],
187    header_libs: ["libc_headers"],
188    ldflags: [
189        "-Wl,--exclude-libs=libgcc.a",
190        "-Wl,--exclude-libs=libgcc_stripped.a",
191        "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
192        "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
193        "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
194        "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
195    ],
196    arch: {
197        x86: {
198            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
199        },
200        x86_64: {
201            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
202        },
203    },
204    include_build_directory: false,
205}
206`,
207		ExpectedBazelTargets: makeCcLibraryTargets("fake-ld-android", AttrNameToString{
208			"srcs": `["ld_android.cpp"]`,
209			"copts": `[
210        "-Wall",
211        "-Wextra",
212        "-Wunused",
213        "-Werror",
214    ]`,
215			"implementation_deps": `[":libc_headers"]`,
216			"linkopts": `[
217        "-Wl,--exclude-libs=libgcc.a",
218        "-Wl,--exclude-libs=libgcc_stripped.a",
219        "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
220        "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
221        "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
222        "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
223    ] + select({
224        "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=libgcc_eh.a"],
225        "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
226        "//conditions:default": [],
227    })`,
228		}),
229	})
230}
231
232func TestCcLibraryExcludeSrcs(t *testing.T) {
233	runCcLibraryTestCase(t, Bp2buildTestCase{
234		Description:                "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math",
235		ModuleTypeUnderTest:        "cc_library",
236		ModuleTypeUnderTestFactory: cc.LibraryFactory,
237		Dir:                        "external",
238		Filesystem: map[string]string{
239			"external/math/cosf.c":      "",
240			"external/math/erf.c":       "",
241			"external/math/erf_data.c":  "",
242			"external/math/erff.c":      "",
243			"external/math/erff_data.c": "",
244			"external/Android.bp": `
245cc_library {
246    name: "fake-libarm-optimized-routines-math",
247    exclude_srcs: [
248        // Provided by:
249        // bionic/libm/upstream-freebsd/lib/msun/src/s_erf.c
250        // bionic/libm/upstream-freebsd/lib/msun/src/s_erff.c
251        "math/erf.c",
252        "math/erf_data.c",
253        "math/erff.c",
254        "math/erff_data.c",
255    ],
256    srcs: [
257        "math/*.c",
258    ],
259    // arch-specific settings
260    arch: {
261        arm64: {
262            cflags: [
263                "-DHAVE_FAST_FMA=1",
264            ],
265        },
266    },
267    bazel_module: { bp2build_available: true },
268}
269`,
270		},
271		Blueprint: soongCcLibraryPreamble,
272		ExpectedBazelTargets: makeCcLibraryTargets("fake-libarm-optimized-routines-math", AttrNameToString{
273			"copts": `select({
274        "//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
275        "//conditions:default": [],
276    })`,
277			"local_includes": `["."]`,
278			"srcs_c":         `["math/cosf.c"]`,
279		}),
280	})
281}
282
283func TestCcLibrarySharedStaticProps(t *testing.T) {
284	runCcLibraryTestCase(t, Bp2buildTestCase{
285		Description:                "cc_library shared/static props",
286		ModuleTypeUnderTest:        "cc_library",
287		ModuleTypeUnderTestFactory: cc.LibraryFactory,
288		Filesystem: map[string]string{
289			"both.cpp":       "",
290			"sharedonly.cpp": "",
291			"staticonly.cpp": "",
292		},
293		Blueprint: soongCcLibraryPreamble + `
294cc_library {
295    name: "a",
296    srcs: ["both.cpp"],
297    cflags: ["bothflag"],
298    shared_libs: ["shared_dep_for_both"],
299    static_libs: ["static_dep_for_both", "whole_and_static_lib_for_both"],
300    whole_static_libs: ["whole_static_lib_for_both", "whole_and_static_lib_for_both"],
301    static: {
302        srcs: ["staticonly.cpp"],
303        cflags: ["staticflag"],
304        shared_libs: ["shared_dep_for_static"],
305        static_libs: ["static_dep_for_static"],
306        whole_static_libs: ["whole_static_lib_for_static"],
307    },
308    shared: {
309        srcs: ["sharedonly.cpp"],
310        cflags: ["sharedflag"],
311        shared_libs: ["shared_dep_for_shared"],
312        static_libs: ["static_dep_for_shared"],
313        whole_static_libs: ["whole_static_lib_for_shared"],
314    },
315    include_build_directory: false,
316}
317
318cc_library_static {
319    name: "static_dep_for_shared",
320    bazel_module: { bp2build_available: false },
321}
322
323cc_library_static {
324    name: "static_dep_for_static",
325    bazel_module: { bp2build_available: false },
326}
327
328cc_library_static {
329    name: "static_dep_for_both",
330    bazel_module: { bp2build_available: false },
331}
332
333cc_library_static {
334    name: "whole_static_lib_for_shared",
335    bazel_module: { bp2build_available: false },
336}
337
338cc_library_static {
339    name: "whole_static_lib_for_static",
340    bazel_module: { bp2build_available: false },
341}
342
343cc_library_static {
344    name: "whole_static_lib_for_both",
345    bazel_module: { bp2build_available: false },
346}
347
348cc_library_static {
349    name: "whole_and_static_lib_for_both",
350    bazel_module: { bp2build_available: false },
351}
352
353cc_library {
354    name: "shared_dep_for_shared",
355    bazel_module: { bp2build_available: false },
356}
357
358cc_library {
359    name: "shared_dep_for_static",
360    bazel_module: { bp2build_available: false },
361}
362
363cc_library {
364    name: "shared_dep_for_both",
365    bazel_module: { bp2build_available: false },
366}
367`,
368		ExpectedBazelTargets: []string{
369			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
370				"copts": `[
371        "bothflag",
372        "staticflag",
373    ]`,
374				"implementation_deps": `[
375        ":static_dep_for_both",
376        ":static_dep_for_static",
377    ]`,
378				"implementation_dynamic_deps": `[
379        ":shared_dep_for_both",
380        ":shared_dep_for_static",
381    ]`,
382				"srcs": `[
383        "both.cpp",
384        "staticonly.cpp",
385    ]`,
386				"whole_archive_deps": `[
387        ":whole_static_lib_for_both",
388        ":whole_and_static_lib_for_both",
389        ":whole_static_lib_for_static",
390    ]`}),
391			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
392				"copts": `[
393        "bothflag",
394        "sharedflag",
395    ]`,
396				"implementation_deps": `[
397        ":static_dep_for_both",
398        ":static_dep_for_shared",
399    ]`,
400				"implementation_dynamic_deps": `[
401        ":shared_dep_for_both",
402        ":shared_dep_for_shared",
403    ]`,
404				"srcs": `[
405        "both.cpp",
406        "sharedonly.cpp",
407    ]`,
408				"whole_archive_deps": `[
409        ":whole_static_lib_for_both",
410        ":whole_and_static_lib_for_both",
411        ":whole_static_lib_for_shared",
412    ]`,
413			}),
414		},
415	})
416}
417
418func TestCcLibraryDeps(t *testing.T) {
419	runCcLibraryTestCase(t, Bp2buildTestCase{
420		Description:                "cc_library shared/static props",
421		ModuleTypeUnderTest:        "cc_library",
422		ModuleTypeUnderTestFactory: cc.LibraryFactory,
423		Filesystem: map[string]string{
424			"both.cpp":       "",
425			"sharedonly.cpp": "",
426			"staticonly.cpp": "",
427		},
428		Blueprint: soongCcLibraryPreamble + `
429cc_library {
430    name: "a",
431    srcs: ["both.cpp"],
432    cflags: ["bothflag"],
433    shared_libs: ["implementation_shared_dep_for_both", "shared_dep_for_both"],
434    export_shared_lib_headers: ["shared_dep_for_both"],
435    static_libs: ["implementation_static_dep_for_both", "static_dep_for_both"],
436    export_static_lib_headers: ["static_dep_for_both", "whole_static_dep_for_both"],
437    whole_static_libs: ["not_explicitly_exported_whole_static_dep_for_both", "whole_static_dep_for_both"],
438    static: {
439        srcs: ["staticonly.cpp"],
440        cflags: ["staticflag"],
441        shared_libs: ["implementation_shared_dep_for_static", "shared_dep_for_static"],
442        export_shared_lib_headers: ["shared_dep_for_static"],
443        static_libs: ["implementation_static_dep_for_static", "static_dep_for_static"],
444        export_static_lib_headers: ["static_dep_for_static", "whole_static_dep_for_static"],
445        whole_static_libs: ["not_explicitly_exported_whole_static_dep_for_static", "whole_static_dep_for_static"],
446    },
447    shared: {
448        srcs: ["sharedonly.cpp"],
449        cflags: ["sharedflag"],
450        shared_libs: ["implementation_shared_dep_for_shared", "shared_dep_for_shared"],
451        export_shared_lib_headers: ["shared_dep_for_shared"],
452        static_libs: ["implementation_static_dep_for_shared", "static_dep_for_shared"],
453        export_static_lib_headers: ["static_dep_for_shared", "whole_static_dep_for_shared"],
454        whole_static_libs: ["not_explicitly_exported_whole_static_dep_for_shared", "whole_static_dep_for_shared"],
455    },
456    include_build_directory: false,
457}
458` + simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_shared") +
459			simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_shared") +
460			simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_static") +
461			simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_static") +
462			simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_both") +
463			simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_both") +
464			simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_shared") +
465			simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_shared") +
466			simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_static") +
467			simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_static") +
468			simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_both") +
469			simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_both") +
470			simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_shared") +
471			simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_shared") +
472			simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_static") +
473			simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_static") +
474			simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") +
475			simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"),
476		ExpectedBazelTargets: []string{
477			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
478				"copts": `[
479        "bothflag",
480        "staticflag",
481    ]`,
482				"deps": `[
483        ":static_dep_for_both",
484        ":static_dep_for_static",
485    ]`,
486				"dynamic_deps": `[
487        ":shared_dep_for_both",
488        ":shared_dep_for_static",
489    ]`,
490				"implementation_deps": `[
491        ":implementation_static_dep_for_both",
492        ":implementation_static_dep_for_static",
493    ]`,
494				"implementation_dynamic_deps": `[
495        ":implementation_shared_dep_for_both",
496        ":implementation_shared_dep_for_static",
497    ]`,
498				"srcs": `[
499        "both.cpp",
500        "staticonly.cpp",
501    ]`,
502				"whole_archive_deps": `[
503        ":not_explicitly_exported_whole_static_dep_for_both",
504        ":whole_static_dep_for_both",
505        ":not_explicitly_exported_whole_static_dep_for_static",
506        ":whole_static_dep_for_static",
507    ]`,
508			}),
509			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
510				"copts": `[
511        "bothflag",
512        "sharedflag",
513    ]`,
514				"deps": `[
515        ":static_dep_for_both",
516        ":static_dep_for_shared",
517    ]`,
518				"dynamic_deps": `[
519        ":shared_dep_for_both",
520        ":shared_dep_for_shared",
521    ]`,
522				"implementation_deps": `[
523        ":implementation_static_dep_for_both",
524        ":implementation_static_dep_for_shared",
525    ]`,
526				"implementation_dynamic_deps": `[
527        ":implementation_shared_dep_for_both",
528        ":implementation_shared_dep_for_shared",
529    ]`,
530				"srcs": `[
531        "both.cpp",
532        "sharedonly.cpp",
533    ]`,
534				"whole_archive_deps": `[
535        ":not_explicitly_exported_whole_static_dep_for_both",
536        ":whole_static_dep_for_both",
537        ":not_explicitly_exported_whole_static_dep_for_shared",
538        ":whole_static_dep_for_shared",
539    ]`,
540			})},
541	},
542	)
543}
544
545func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) {
546	runCcLibraryTestCase(t, Bp2buildTestCase{
547		ModuleTypeUnderTest:        "cc_library",
548		ModuleTypeUnderTestFactory: cc.LibraryFactory,
549		Dir:                        "foo/bar",
550		Filesystem: map[string]string{
551			"foo/bar/Android.bp": `
552cc_library {
553    name: "a",
554    whole_static_libs: ["whole_static_lib_for_both"],
555    static: {
556        whole_static_libs: ["whole_static_lib_for_static"],
557    },
558    shared: {
559        whole_static_libs: ["whole_static_lib_for_shared"],
560    },
561    bazel_module: { bp2build_available: true },
562    include_build_directory: false,
563}
564
565cc_prebuilt_library_static { name: "whole_static_lib_for_shared" }
566
567cc_prebuilt_library_static { name: "whole_static_lib_for_static" }
568
569cc_prebuilt_library_static { name: "whole_static_lib_for_both" }
570`,
571		},
572		Blueprint: soongCcLibraryPreamble,
573		ExpectedBazelTargets: []string{
574			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
575				"whole_archive_deps": `[
576        ":whole_static_lib_for_both_alwayslink",
577        ":whole_static_lib_for_static_alwayslink",
578    ]`,
579			}),
580			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
581				"whole_archive_deps": `[
582        ":whole_static_lib_for_both_alwayslink",
583        ":whole_static_lib_for_shared_alwayslink",
584    ]`,
585			}),
586		},
587	},
588	)
589}
590
591func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
592	runCcLibraryTestCase(t, Bp2buildTestCase{
593		Description:                "cc_library shared/static props in arch",
594		ModuleTypeUnderTest:        "cc_library",
595		ModuleTypeUnderTestFactory: cc.LibraryFactory,
596		Dir:                        "foo/bar",
597		Filesystem: map[string]string{
598			"foo/bar/arm.cpp":        "",
599			"foo/bar/x86.cpp":        "",
600			"foo/bar/sharedonly.cpp": "",
601			"foo/bar/staticonly.cpp": "",
602			"foo/bar/Android.bp": `
603cc_library {
604    name: "a",
605    arch: {
606        arm: {
607            shared: {
608                srcs: ["arm_shared.cpp"],
609                cflags: ["-DARM_SHARED"],
610                static_libs: ["arm_static_dep_for_shared"],
611                whole_static_libs: ["arm_whole_static_dep_for_shared"],
612                shared_libs: ["arm_shared_dep_for_shared"],
613            },
614        },
615        x86: {
616            static: {
617                srcs: ["x86_static.cpp"],
618                cflags: ["-DX86_STATIC"],
619                static_libs: ["x86_dep_for_static"],
620            },
621        },
622    },
623    target: {
624        android: {
625            shared: {
626                srcs: ["android_shared.cpp"],
627                cflags: ["-DANDROID_SHARED"],
628                static_libs: ["android_dep_for_shared"],
629            },
630        },
631        android_arm: {
632            shared: {
633                cflags: ["-DANDROID_ARM_SHARED"],
634            },
635        },
636    },
637    srcs: ["both.cpp"],
638    cflags: ["bothflag"],
639    static_libs: ["static_dep_for_both"],
640    static: {
641        srcs: ["staticonly.cpp"],
642        cflags: ["staticflag"],
643        static_libs: ["static_dep_for_static"],
644    },
645    shared: {
646        srcs: ["sharedonly.cpp"],
647        cflags: ["sharedflag"],
648        static_libs: ["static_dep_for_shared"],
649    },
650    bazel_module: { bp2build_available: true },
651}
652
653cc_library_static { name: "static_dep_for_shared" }
654cc_library_static { name: "static_dep_for_static" }
655cc_library_static { name: "static_dep_for_both" }
656
657cc_library_static { name: "arm_static_dep_for_shared" }
658cc_library_static { name: "arm_whole_static_dep_for_shared" }
659cc_library_static { name: "arm_shared_dep_for_shared" }
660
661cc_library_static { name: "x86_dep_for_static" }
662
663cc_library_static { name: "android_dep_for_shared" }
664`,
665		},
666		Blueprint: soongCcLibraryPreamble,
667		ExpectedBazelTargets: []string{
668			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
669				"copts": `[
670        "bothflag",
671        "staticflag",
672    ] + select({
673        "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
674        "//conditions:default": [],
675    })`,
676				"implementation_deps": `[
677        ":static_dep_for_both",
678        ":static_dep_for_static",
679    ] + select({
680        "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
681        "//conditions:default": [],
682    })`,
683				"local_includes": `["."]`,
684				"srcs": `[
685        "both.cpp",
686        "staticonly.cpp",
687    ] + select({
688        "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
689        "//conditions:default": [],
690    })`,
691			}),
692			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
693				"copts": `[
694        "bothflag",
695        "sharedflag",
696    ] + select({
697        "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
698        "//conditions:default": [],
699    }) + select({
700        "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
701        "//conditions:default": [],
702    }) + select({
703        "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
704        "//conditions:default": [],
705    })`,
706				"implementation_deps": `[
707        ":static_dep_for_both",
708        ":static_dep_for_shared",
709    ] + select({
710        "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
711        "//conditions:default": [],
712    }) + select({
713        "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
714        "//conditions:default": [],
715    })`,
716				"implementation_dynamic_deps": `select({
717        "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
718        "//conditions:default": [],
719    })`,
720				"local_includes": `["."]`,
721				"srcs": `[
722        "both.cpp",
723        "sharedonly.cpp",
724    ] + select({
725        "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
726        "//conditions:default": [],
727    }) + select({
728        "//build/bazel/platforms/os:android": ["android_shared.cpp"],
729        "//conditions:default": [],
730    })`,
731				"whole_archive_deps": `select({
732        "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
733        "//conditions:default": [],
734    })`,
735			}),
736		},
737	},
738	)
739}
740
741func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
742	runCcLibraryTestCase(t, Bp2buildTestCase{
743		Description:                "cc_library shared/static props with c/cpp/s mixed sources",
744		ModuleTypeUnderTest:        "cc_library",
745		ModuleTypeUnderTestFactory: cc.LibraryFactory,
746		Dir:                        "foo/bar",
747		Filesystem: map[string]string{
748			"foo/bar/both_source.cpp":   "",
749			"foo/bar/both_source.cc":    "",
750			"foo/bar/both_source.c":     "",
751			"foo/bar/both_source.s":     "",
752			"foo/bar/both_source.S":     "",
753			"foo/bar/shared_source.cpp": "",
754			"foo/bar/shared_source.cc":  "",
755			"foo/bar/shared_source.c":   "",
756			"foo/bar/shared_source.s":   "",
757			"foo/bar/shared_source.S":   "",
758			"foo/bar/static_source.cpp": "",
759			"foo/bar/static_source.cc":  "",
760			"foo/bar/static_source.c":   "",
761			"foo/bar/static_source.s":   "",
762			"foo/bar/static_source.S":   "",
763			"foo/bar/Android.bp": `
764cc_library {
765    name: "a",
766    srcs: [
767    "both_source.cpp",
768    "both_source.cc",
769    "both_source.c",
770    "both_source.s",
771    "both_source.S",
772    ":both_filegroup",
773  ],
774    static: {
775        srcs: [
776          "static_source.cpp",
777          "static_source.cc",
778          "static_source.c",
779          "static_source.s",
780          "static_source.S",
781          ":static_filegroup",
782        ],
783    },
784    shared: {
785        srcs: [
786          "shared_source.cpp",
787          "shared_source.cc",
788          "shared_source.c",
789          "shared_source.s",
790          "shared_source.S",
791          ":shared_filegroup",
792        ],
793    },
794    bazel_module: { bp2build_available: true },
795}
796
797filegroup {
798    name: "both_filegroup",
799    srcs: [
800        // Not relevant, handled by filegroup macro
801  ],
802}
803
804filegroup {
805    name: "shared_filegroup",
806    srcs: [
807        // Not relevant, handled by filegroup macro
808  ],
809}
810
811filegroup {
812    name: "static_filegroup",
813    srcs: [
814        // Not relevant, handled by filegroup macro
815  ],
816}
817`,
818		},
819		Blueprint: soongCcLibraryPreamble,
820		ExpectedBazelTargets: []string{
821			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
822				"local_includes": `["."]`,
823				"srcs": `[
824        "both_source.cpp",
825        "both_source.cc",
826        ":both_filegroup_cpp_srcs",
827        "static_source.cpp",
828        "static_source.cc",
829        ":static_filegroup_cpp_srcs",
830    ]`,
831				"srcs_as": `[
832        "both_source.s",
833        "both_source.S",
834        ":both_filegroup_as_srcs",
835        "static_source.s",
836        "static_source.S",
837        ":static_filegroup_as_srcs",
838    ]`,
839				"srcs_c": `[
840        "both_source.c",
841        ":both_filegroup_c_srcs",
842        "static_source.c",
843        ":static_filegroup_c_srcs",
844    ]`,
845			}),
846			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
847				"local_includes": `["."]`,
848				"srcs": `[
849        "both_source.cpp",
850        "both_source.cc",
851        ":both_filegroup_cpp_srcs",
852        "shared_source.cpp",
853        "shared_source.cc",
854        ":shared_filegroup_cpp_srcs",
855    ]`,
856				"srcs_as": `[
857        "both_source.s",
858        "both_source.S",
859        ":both_filegroup_as_srcs",
860        "shared_source.s",
861        "shared_source.S",
862        ":shared_filegroup_as_srcs",
863    ]`,
864				"srcs_c": `[
865        "both_source.c",
866        ":both_filegroup_c_srcs",
867        "shared_source.c",
868        ":shared_filegroup_c_srcs",
869    ]`,
870			})}})
871}
872
873func TestCcLibraryNonConfiguredVersionScriptAndDynamicList(t *testing.T) {
874	runCcLibraryTestCase(t, Bp2buildTestCase{
875		Description:                "cc_library non-configured version script and dynamic list",
876		ModuleTypeUnderTest:        "cc_library",
877		ModuleTypeUnderTestFactory: cc.LibraryFactory,
878		Dir:                        "foo/bar",
879		Filesystem: map[string]string{
880			"foo/bar/Android.bp": `
881cc_library {
882    name: "a",
883    srcs: ["a.cpp"],
884    version_script: "v.map",
885    dynamic_list: "dynamic.list",
886    bazel_module: { bp2build_available: true },
887    include_build_directory: false,
888}
889`,
890		},
891		Blueprint: soongCcLibraryPreamble,
892		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
893			"additional_linker_inputs": `[
894        "v.map",
895        "dynamic.list",
896    ]`,
897			"linkopts": `[
898        "-Wl,--version-script,$(location v.map)",
899        "-Wl,--dynamic-list,$(location dynamic.list)",
900    ]`,
901			"srcs": `["a.cpp"]`,
902		}),
903	},
904	)
905}
906
907func TestCcLibraryConfiguredVersionScriptAndDynamicList(t *testing.T) {
908	runCcLibraryTestCase(t, Bp2buildTestCase{
909		Description:                "cc_library configured version script and dynamic list",
910		ModuleTypeUnderTest:        "cc_library",
911		ModuleTypeUnderTestFactory: cc.LibraryFactory,
912		Dir:                        "foo/bar",
913		Filesystem: map[string]string{
914			"foo/bar/Android.bp": `
915cc_library {
916   name: "a",
917   srcs: ["a.cpp"],
918   arch: {
919     arm: {
920       version_script: "arm.map",
921       dynamic_list: "dynamic_arm.list",
922     },
923     arm64: {
924       version_script: "arm64.map",
925       dynamic_list: "dynamic_arm64.list",
926     },
927   },
928
929   bazel_module: { bp2build_available: true },
930    include_build_directory: false,
931}
932    `,
933		},
934		Blueprint: soongCcLibraryPreamble,
935		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
936			"additional_linker_inputs": `select({
937        "//build/bazel/platforms/arch:arm": [
938            "arm.map",
939            "dynamic_arm.list",
940        ],
941        "//build/bazel/platforms/arch:arm64": [
942            "arm64.map",
943            "dynamic_arm64.list",
944        ],
945        "//conditions:default": [],
946    })`,
947			"linkopts": `select({
948        "//build/bazel/platforms/arch:arm": [
949            "-Wl,--version-script,$(location arm.map)",
950            "-Wl,--dynamic-list,$(location dynamic_arm.list)",
951        ],
952        "//build/bazel/platforms/arch:arm64": [
953            "-Wl,--version-script,$(location arm64.map)",
954            "-Wl,--dynamic-list,$(location dynamic_arm64.list)",
955        ],
956        "//conditions:default": [],
957    })`,
958			"srcs": `["a.cpp"]`,
959		}),
960	},
961	)
962}
963
964func TestCcLibraryLdflagsSplitBySpaceExceptSoongAdded(t *testing.T) {
965	runCcLibraryTestCase(t, Bp2buildTestCase{
966		Description:                "ldflags are split by spaces except for the ones added by soong (version script and dynamic list)",
967		ModuleTypeUnderTest:        "cc_library",
968		ModuleTypeUnderTestFactory: cc.LibraryFactory,
969		Filesystem: map[string]string{
970			"version_script": "",
971			"dynamic.list":   "",
972		},
973		Blueprint: `
974cc_library {
975    name: "foo",
976    ldflags: [
977        "--nospace_flag",
978        "-z spaceflag",
979    ],
980    version_script: "version_script",
981    dynamic_list: "dynamic.list",
982    include_build_directory: false,
983}
984`,
985		ExpectedBazelTargets: []string{
986			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
987			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
988				"additional_linker_inputs": `[
989        "version_script",
990        "dynamic.list",
991    ]`,
992				"linkopts": `[
993        "--nospace_flag",
994        "-z",
995        "spaceflag",
996        "-Wl,--version-script,$(location version_script)",
997        "-Wl,--dynamic-list,$(location dynamic.list)",
998    ]`,
999			}),
1000		},
1001	})
1002}
1003
1004func TestCcLibrarySharedLibs(t *testing.T) {
1005	runCcLibraryTestCase(t, Bp2buildTestCase{
1006		Description:                "cc_library shared_libs",
1007		ModuleTypeUnderTest:        "cc_library",
1008		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1009		Blueprint: soongCcLibraryPreamble + `
1010cc_library {
1011    name: "mylib",
1012    bazel_module: { bp2build_available: false },
1013}
1014
1015cc_library {
1016    name: "a",
1017    shared_libs: ["mylib",],
1018    include_build_directory: false,
1019}
1020`,
1021		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
1022			"implementation_dynamic_deps": `[":mylib"]`,
1023		}),
1024	},
1025	)
1026}
1027
1028func TestCcLibraryFeatures(t *testing.T) {
1029	expected_targets := []string{}
1030	expected_targets = append(expected_targets, makeCcLibraryTargets("a", AttrNameToString{
1031		"features": `[
1032        "disable_pack_relocations",
1033        "-no_undefined_symbols",
1034    ]`,
1035		"native_coverage": `False`,
1036		"srcs":            `["a.cpp"]`,
1037	})...)
1038	expected_targets = append(expected_targets, makeCcLibraryTargets("b", AttrNameToString{
1039		"features": `select({
1040        "//build/bazel/platforms/arch:x86_64": [
1041            "disable_pack_relocations",
1042            "-no_undefined_symbols",
1043        ],
1044        "//conditions:default": [],
1045    })`,
1046		"native_coverage": `False`,
1047		"srcs":            `["b.cpp"]`,
1048	})...)
1049	expected_targets = append(expected_targets, makeCcLibraryTargets("c", AttrNameToString{
1050		"features": `select({
1051        "//build/bazel/platforms/os:darwin": [
1052            "disable_pack_relocations",
1053            "-no_undefined_symbols",
1054        ],
1055        "//conditions:default": [],
1056    })`,
1057		"srcs": `["c.cpp"]`,
1058	})...)
1059
1060	runCcLibraryTestCase(t, Bp2buildTestCase{
1061		Description:                "cc_library pack_relocations test",
1062		ModuleTypeUnderTest:        "cc_library",
1063		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1064		Blueprint: soongCcLibraryPreamble + `
1065cc_library {
1066    name: "a",
1067    srcs: ["a.cpp"],
1068    pack_relocations: false,
1069    allow_undefined_symbols: true,
1070    include_build_directory: false,
1071    native_coverage: false,
1072}
1073
1074cc_library {
1075    name: "b",
1076    srcs: ["b.cpp"],
1077    arch: {
1078        x86_64: {
1079            pack_relocations: false,
1080            allow_undefined_symbols: true,
1081        },
1082    },
1083    include_build_directory: false,
1084    native_coverage: false,
1085}
1086
1087cc_library {
1088    name: "c",
1089    srcs: ["c.cpp"],
1090    target: {
1091        darwin: {
1092            pack_relocations: false,
1093            allow_undefined_symbols: true,
1094        },
1095    },
1096    include_build_directory: false,
1097}`,
1098		ExpectedBazelTargets: expected_targets,
1099	})
1100}
1101
1102func TestCcLibrarySpacesInCopts(t *testing.T) {
1103	runCcLibraryTestCase(t, Bp2buildTestCase{
1104		Description:                "cc_library spaces in copts",
1105		ModuleTypeUnderTest:        "cc_library",
1106		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1107		Blueprint: soongCcLibraryPreamble + `
1108cc_library {
1109    name: "a",
1110    cflags: ["-include header.h",],
1111    include_build_directory: false,
1112}
1113`,
1114		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
1115			"copts": `[
1116        "-include",
1117        "header.h",
1118    ]`,
1119		}),
1120	},
1121	)
1122}
1123
1124func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
1125	runCcLibraryTestCase(t, Bp2buildTestCase{
1126		Description:                "cc_library cppflags usage",
1127		ModuleTypeUnderTest:        "cc_library",
1128		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1129		Blueprint: soongCcLibraryPreamble + `cc_library {
1130    name: "a",
1131    srcs: ["a.cpp"],
1132    cflags: ["-Wall"],
1133    cppflags: [
1134        "-fsigned-char",
1135        "-pedantic",
1136    ],
1137    arch: {
1138        arm64: {
1139            cppflags: ["-DARM64=1"],
1140        },
1141    },
1142    target: {
1143        android: {
1144            cppflags: ["-DANDROID=1"],
1145        },
1146    },
1147    include_build_directory: false,
1148}
1149`,
1150		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
1151			"copts": `["-Wall"]`,
1152			"cppflags": `[
1153        "-fsigned-char",
1154        "-pedantic",
1155    ] + select({
1156        "//build/bazel/platforms/arch:arm64": ["-DARM64=1"],
1157        "//conditions:default": [],
1158    }) + select({
1159        "//build/bazel/platforms/os:android": ["-DANDROID=1"],
1160        "//conditions:default": [],
1161    })`,
1162			"srcs": `["a.cpp"]`,
1163		}),
1164	},
1165	)
1166}
1167
1168func TestCcLibraryExcludeLibs(t *testing.T) {
1169	runCcLibraryTestCase(t, Bp2buildTestCase{
1170		ModuleTypeUnderTest:        "cc_library",
1171		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1172		Filesystem:                 map[string]string{},
1173		Blueprint: soongCcLibraryStaticPreamble + `
1174cc_library {
1175    name: "foo_static",
1176    srcs: ["common.c"],
1177    whole_static_libs: [
1178        "arm_whole_static_lib_excludes",
1179        "malloc_not_svelte_whole_static_lib_excludes"
1180    ],
1181    static_libs: [
1182        "arm_static_lib_excludes",
1183        "malloc_not_svelte_static_lib_excludes"
1184    ],
1185    shared_libs: [
1186        "arm_shared_lib_excludes",
1187    ],
1188    arch: {
1189        arm: {
1190            exclude_shared_libs: [
1191                 "arm_shared_lib_excludes",
1192            ],
1193            exclude_static_libs: [
1194                "arm_static_lib_excludes",
1195                "arm_whole_static_lib_excludes",
1196            ],
1197        },
1198    },
1199    product_variables: {
1200        malloc_not_svelte: {
1201            shared_libs: ["malloc_not_svelte_shared_lib"],
1202            whole_static_libs: ["malloc_not_svelte_whole_static_lib"],
1203            exclude_static_libs: [
1204                "malloc_not_svelte_static_lib_excludes",
1205                "malloc_not_svelte_whole_static_lib_excludes",
1206            ],
1207        },
1208    },
1209    include_build_directory: false,
1210}
1211
1212cc_library {
1213    name: "arm_whole_static_lib_excludes",
1214    bazel_module: { bp2build_available: false },
1215}
1216
1217cc_library {
1218    name: "malloc_not_svelte_whole_static_lib",
1219    bazel_module: { bp2build_available: false },
1220}
1221
1222cc_library {
1223    name: "malloc_not_svelte_whole_static_lib_excludes",
1224    bazel_module: { bp2build_available: false },
1225}
1226
1227cc_library {
1228    name: "arm_static_lib_excludes",
1229    bazel_module: { bp2build_available: false },
1230}
1231
1232cc_library {
1233    name: "malloc_not_svelte_static_lib_excludes",
1234    bazel_module: { bp2build_available: false },
1235}
1236
1237cc_library {
1238    name: "arm_shared_lib_excludes",
1239    bazel_module: { bp2build_available: false },
1240}
1241
1242cc_library {
1243    name: "malloc_not_svelte_shared_lib",
1244    bazel_module: { bp2build_available: false },
1245}
1246`,
1247		ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
1248			"implementation_deps": `select({
1249        "//build/bazel/platforms/arch:arm": [],
1250        "//conditions:default": [":arm_static_lib_excludes_bp2build_cc_library_static"],
1251    }) + select({
1252        "//build/bazel/product_variables:malloc_not_svelte": [],
1253        "//conditions:default": [":malloc_not_svelte_static_lib_excludes_bp2build_cc_library_static"],
1254    })`,
1255			"implementation_dynamic_deps": `select({
1256        "//build/bazel/platforms/arch:arm": [],
1257        "//conditions:default": [":arm_shared_lib_excludes"],
1258    }) + select({
1259        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
1260        "//conditions:default": [],
1261    })`,
1262			"srcs_c": `["common.c"]`,
1263			"whole_archive_deps": `select({
1264        "//build/bazel/platforms/arch:arm": [],
1265        "//conditions:default": [":arm_whole_static_lib_excludes_bp2build_cc_library_static"],
1266    }) + select({
1267        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib_bp2build_cc_library_static"],
1268        "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes_bp2build_cc_library_static"],
1269    })`,
1270		}),
1271	},
1272	)
1273}
1274
1275func TestCcLibraryProductVariablesHeaderLibs(t *testing.T) {
1276	runCcLibraryTestCase(t, Bp2buildTestCase{
1277		ModuleTypeUnderTest:        "cc_library",
1278		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1279		Filesystem:                 map[string]string{},
1280		Blueprint: soongCcLibraryStaticPreamble + `
1281cc_library {
1282    name: "foo_static",
1283    srcs: ["common.c"],
1284    product_variables: {
1285        malloc_not_svelte: {
1286            header_libs: ["malloc_not_svelte_header_lib"],
1287        },
1288    },
1289    include_build_directory: false,
1290}
1291
1292cc_library {
1293    name: "malloc_not_svelte_header_lib",
1294    bazel_module: { bp2build_available: false },
1295}
1296`,
1297		ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
1298			"implementation_deps": `select({
1299        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_header_lib"],
1300        "//conditions:default": [],
1301    })`,
1302			"srcs_c":                 `["common.c"]`,
1303			"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
1304		}),
1305	},
1306	)
1307}
1308
1309func TestCCLibraryNoCrtTrue(t *testing.T) {
1310	runCcLibraryTestCase(t, Bp2buildTestCase{
1311		Description:                "cc_library - nocrt: true disables feature",
1312		ModuleTypeUnderTest:        "cc_library",
1313		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1314		Filesystem: map[string]string{
1315			"impl.cpp": "",
1316		},
1317		Blueprint: soongCcLibraryPreamble + `
1318cc_library {
1319    name: "foo-lib",
1320    srcs: ["impl.cpp"],
1321    nocrt: true,
1322    include_build_directory: false,
1323}
1324`,
1325		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1326			"features": `["-link_crt"]`,
1327			"srcs":     `["impl.cpp"]`,
1328		}),
1329	},
1330	)
1331}
1332
1333func TestCCLibraryNoCrtFalse(t *testing.T) {
1334	runCcLibraryTestCase(t, Bp2buildTestCase{
1335		Description:                "cc_library - nocrt: false - does not emit attribute",
1336		ModuleTypeUnderTest:        "cc_library",
1337		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1338		Filesystem: map[string]string{
1339			"impl.cpp": "",
1340		},
1341		Blueprint: soongCcLibraryPreamble + `
1342cc_library {
1343    name: "foo-lib",
1344    srcs: ["impl.cpp"],
1345    nocrt: false,
1346    include_build_directory: false,
1347}
1348`,
1349		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1350			"srcs": `["impl.cpp"]`,
1351		}),
1352	})
1353}
1354
1355func TestCCLibraryNoCrtArchVariant(t *testing.T) {
1356	runCcLibraryTestCase(t, Bp2buildTestCase{
1357		Description:                "cc_library - nocrt in select",
1358		ModuleTypeUnderTest:        "cc_library",
1359		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1360		Filesystem: map[string]string{
1361			"impl.cpp": "",
1362		},
1363		Blueprint: soongCcLibraryPreamble + `
1364cc_library {
1365    name: "foo-lib",
1366    srcs: ["impl.cpp"],
1367    arch: {
1368        arm: {
1369            nocrt: true,
1370        },
1371        x86: {
1372            nocrt: false,
1373        },
1374    },
1375    include_build_directory: false,
1376}
1377`,
1378		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1379			"features": `select({
1380        "//build/bazel/platforms/arch:arm": ["-link_crt"],
1381        "//conditions:default": [],
1382    })`,
1383			"srcs": `["impl.cpp"]`,
1384		}),
1385	})
1386}
1387
1388func TestCCLibraryNoLibCrtTrue(t *testing.T) {
1389	runCcLibraryTestCase(t, Bp2buildTestCase{
1390		ModuleTypeUnderTest:        "cc_library",
1391		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1392		Filesystem: map[string]string{
1393			"impl.cpp": "",
1394		},
1395		Blueprint: soongCcLibraryPreamble + `
1396cc_library {
1397    name: "foo-lib",
1398    srcs: ["impl.cpp"],
1399    no_libcrt: true,
1400    include_build_directory: false,
1401}
1402`,
1403		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1404			"features": `["-use_libcrt"]`,
1405			"srcs":     `["impl.cpp"]`,
1406		}),
1407	})
1408}
1409
1410func makeCcLibraryTargets(name string, attrs AttrNameToString) []string {
1411	STATIC_ONLY_ATTRS := map[string]bool{}
1412	SHARED_ONLY_ATTRS := map[string]bool{
1413		"link_crt":                 true,
1414		"additional_linker_inputs": true,
1415		"linkopts":                 true,
1416		"strip":                    true,
1417		"inject_bssl_hash":         true,
1418		"stubs_symbol_file":        true,
1419		"use_version_lib":          true,
1420	}
1421
1422	sharedAttrs := AttrNameToString{}
1423	staticAttrs := AttrNameToString{}
1424	for key, val := range attrs {
1425		if _, staticOnly := STATIC_ONLY_ATTRS[key]; !staticOnly {
1426			sharedAttrs[key] = val
1427		}
1428		if _, sharedOnly := SHARED_ONLY_ATTRS[key]; !sharedOnly {
1429			staticAttrs[key] = val
1430		}
1431	}
1432	sharedTarget := MakeBazelTarget("cc_library_shared", name, sharedAttrs)
1433	staticTarget := MakeBazelTarget("cc_library_static", name+"_bp2build_cc_library_static", staticAttrs)
1434
1435	return []string{staticTarget, sharedTarget}
1436}
1437
1438func TestCCLibraryNoLibCrtFalse(t *testing.T) {
1439	runCcLibraryTestCase(t, Bp2buildTestCase{
1440		ModuleTypeUnderTest:        "cc_library",
1441		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1442		Filesystem: map[string]string{
1443			"impl.cpp": "",
1444		},
1445		Blueprint: soongCcLibraryPreamble + `
1446cc_library {
1447    name: "foo-lib",
1448    srcs: ["impl.cpp"],
1449    no_libcrt: false,
1450    include_build_directory: false,
1451}
1452`,
1453		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1454			"srcs": `["impl.cpp"]`,
1455		}),
1456	})
1457}
1458
1459func TestCCLibraryNoLibCrtArchVariant(t *testing.T) {
1460	runCcLibraryTestCase(t, Bp2buildTestCase{
1461		ModuleTypeUnderTest:        "cc_library",
1462		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1463		Filesystem: map[string]string{
1464			"impl.cpp": "",
1465		},
1466		Blueprint: soongCcLibraryPreamble + `
1467cc_library {
1468    name: "foo-lib",
1469    srcs: ["impl.cpp"],
1470    arch: {
1471        arm: {
1472            no_libcrt: true,
1473        },
1474        x86: {
1475            no_libcrt: true,
1476        },
1477    },
1478    include_build_directory: false,
1479}
1480`,
1481		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1482			"srcs": `["impl.cpp"]`,
1483			"features": `select({
1484        "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
1485        "//build/bazel/platforms/arch:x86": ["-use_libcrt"],
1486        "//conditions:default": [],
1487    })`,
1488		}),
1489	})
1490}
1491
1492func TestCCLibraryNoLibCrtArchAndTargetVariant(t *testing.T) {
1493	runCcLibraryTestCase(t, Bp2buildTestCase{
1494		ModuleTypeUnderTest:        "cc_library",
1495		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1496		Filesystem: map[string]string{
1497			"impl.cpp": "",
1498		},
1499		Blueprint: soongCcLibraryPreamble + `
1500cc_library {
1501    name: "foo-lib",
1502    srcs: ["impl.cpp"],
1503    arch: {
1504        arm: {
1505            no_libcrt: true,
1506        },
1507        x86: {
1508            no_libcrt: true,
1509        },
1510    },
1511    target: {
1512        darwin: {
1513            no_libcrt: true,
1514        }
1515    },
1516    include_build_directory: false,
1517}
1518`,
1519		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1520			"features": `select({
1521        "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
1522        "//build/bazel/platforms/arch:x86": ["-use_libcrt"],
1523        "//conditions:default": [],
1524    }) + select({
1525        "//build/bazel/platforms/os:darwin": ["-use_libcrt"],
1526        "//conditions:default": [],
1527    })`,
1528			"srcs": `["impl.cpp"]`,
1529		}),
1530	})
1531}
1532
1533func TestCCLibraryNoLibCrtArchAndTargetVariantConflict(t *testing.T) {
1534	runCcLibraryTestCase(t, Bp2buildTestCase{
1535		ModuleTypeUnderTest:        "cc_library",
1536		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1537		Filesystem: map[string]string{
1538			"impl.cpp": "",
1539		},
1540		Blueprint: soongCcLibraryPreamble + `
1541cc_library {
1542    name: "foo-lib",
1543    srcs: ["impl.cpp"],
1544    arch: {
1545        arm: {
1546            no_libcrt: true,
1547        },
1548        // This is expected to override the value for darwin_x86_64.
1549        x86_64: {
1550            no_libcrt: true,
1551        },
1552    },
1553    target: {
1554        darwin: {
1555            no_libcrt: false,
1556        }
1557    },
1558    include_build_directory: false,
1559}
1560`,
1561		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1562			"srcs": `["impl.cpp"]`,
1563			"features": `select({
1564        "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
1565        "//build/bazel/platforms/arch:x86_64": ["-use_libcrt"],
1566        "//conditions:default": [],
1567    })`,
1568		}),
1569	})
1570}
1571
1572func TestCcLibraryStrip(t *testing.T) {
1573	expectedTargets := []string{}
1574	expectedTargets = append(expectedTargets, makeCcLibraryTargets("all", AttrNameToString{
1575		"strip": `{
1576        "all": True,
1577    }`,
1578	})...)
1579	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols", AttrNameToString{
1580		"strip": `{
1581        "keep_symbols": True,
1582    }`,
1583	})...)
1584	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_and_debug_frame", AttrNameToString{
1585		"strip": `{
1586        "keep_symbols_and_debug_frame": True,
1587    }`,
1588	})...)
1589	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_list", AttrNameToString{
1590		"strip": `{
1591        "keep_symbols_list": ["symbol"],
1592    }`,
1593	})...)
1594	expectedTargets = append(expectedTargets, makeCcLibraryTargets("none", AttrNameToString{
1595		"strip": `{
1596        "none": True,
1597    }`,
1598	})...)
1599	expectedTargets = append(expectedTargets, makeCcLibraryTargets("nothing", AttrNameToString{})...)
1600
1601	runCcLibraryTestCase(t, Bp2buildTestCase{
1602		Description:                "cc_library strip args",
1603		ModuleTypeUnderTest:        "cc_library",
1604		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1605		Blueprint: soongCcLibraryPreamble + `
1606cc_library {
1607    name: "nothing",
1608    include_build_directory: false,
1609}
1610cc_library {
1611    name: "keep_symbols",
1612    strip: {
1613        keep_symbols: true,
1614    },
1615    include_build_directory: false,
1616}
1617cc_library {
1618    name: "keep_symbols_and_debug_frame",
1619    strip: {
1620        keep_symbols_and_debug_frame: true,
1621    },
1622    include_build_directory: false,
1623}
1624cc_library {
1625    name: "none",
1626    strip: {
1627        none: true,
1628    },
1629    include_build_directory: false,
1630}
1631cc_library {
1632    name: "keep_symbols_list",
1633    strip: {
1634        keep_symbols_list: ["symbol"],
1635    },
1636    include_build_directory: false,
1637}
1638cc_library {
1639    name: "all",
1640    strip: {
1641        all: true,
1642    },
1643    include_build_directory: false,
1644}
1645`,
1646		ExpectedBazelTargets: expectedTargets,
1647	})
1648}
1649
1650func TestCcLibraryStripWithArch(t *testing.T) {
1651	runCcLibraryTestCase(t, Bp2buildTestCase{
1652		Description:                "cc_library strip args",
1653		ModuleTypeUnderTest:        "cc_library",
1654		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1655		Blueprint: soongCcLibraryPreamble + `
1656cc_library {
1657    name: "multi-arch",
1658    target: {
1659        darwin: {
1660            strip: {
1661                keep_symbols_list: ["foo", "bar"]
1662            }
1663        },
1664    },
1665    arch: {
1666        arm: {
1667            strip: {
1668                keep_symbols_and_debug_frame: true,
1669            },
1670        },
1671        arm64: {
1672            strip: {
1673                keep_symbols: true,
1674            },
1675        },
1676    },
1677    include_build_directory: false,
1678}
1679`,
1680		ExpectedBazelTargets: makeCcLibraryTargets("multi-arch", AttrNameToString{
1681			"strip": `{
1682        "keep_symbols": select({
1683            "//build/bazel/platforms/arch:arm64": True,
1684            "//conditions:default": None,
1685        }),
1686        "keep_symbols_and_debug_frame": select({
1687            "//build/bazel/platforms/arch:arm": True,
1688            "//conditions:default": None,
1689        }),
1690        "keep_symbols_list": select({
1691            "//build/bazel/platforms/os:darwin": [
1692                "foo",
1693                "bar",
1694            ],
1695            "//conditions:default": [],
1696        }),
1697    }`,
1698		}),
1699	},
1700	)
1701}
1702
1703func TestCcLibrary_SystemSharedLibsRootEmpty(t *testing.T) {
1704	runCcLibraryTestCase(t, Bp2buildTestCase{
1705		Description:                "cc_library system_shared_libs empty at root",
1706		ModuleTypeUnderTest:        "cc_library",
1707		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1708		Blueprint: soongCcLibraryPreamble + `
1709cc_library {
1710    name: "root_empty",
1711    system_shared_libs: [],
1712    include_build_directory: false,
1713}
1714`,
1715		ExpectedBazelTargets: makeCcLibraryTargets("root_empty", AttrNameToString{
1716			"system_dynamic_deps": `[]`,
1717		}),
1718	},
1719	)
1720}
1721
1722func TestCcLibrary_SystemSharedLibsStaticEmpty(t *testing.T) {
1723	runCcLibraryTestCase(t, Bp2buildTestCase{
1724		Description:                "cc_library system_shared_libs empty for static variant",
1725		ModuleTypeUnderTest:        "cc_library",
1726		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1727		Blueprint: soongCcLibraryPreamble + `
1728cc_library {
1729    name: "static_empty",
1730    static: {
1731        system_shared_libs: [],
1732    },
1733    include_build_directory: false,
1734}
1735`,
1736		ExpectedBazelTargets: []string{
1737			MakeBazelTarget("cc_library_static", "static_empty_bp2build_cc_library_static", AttrNameToString{
1738				"system_dynamic_deps": "[]",
1739			}),
1740			MakeBazelTarget("cc_library_shared", "static_empty", AttrNameToString{}),
1741		},
1742	})
1743}
1744
1745func TestCcLibrary_SystemSharedLibsSharedEmpty(t *testing.T) {
1746	runCcLibraryTestCase(t, Bp2buildTestCase{
1747		Description:                "cc_library system_shared_libs empty for shared variant",
1748		ModuleTypeUnderTest:        "cc_library",
1749		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1750		Blueprint: soongCcLibraryPreamble + `
1751cc_library {
1752    name: "shared_empty",
1753    shared: {
1754        system_shared_libs: [],
1755    },
1756    include_build_directory: false,
1757}
1758`,
1759		ExpectedBazelTargets: []string{
1760			MakeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
1761			MakeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
1762				"system_dynamic_deps": "[]",
1763			}),
1764		},
1765	})
1766}
1767
1768func TestCcLibrary_SystemSharedLibsSharedBionicEmpty(t *testing.T) {
1769	runCcLibraryTestCase(t, Bp2buildTestCase{
1770		Description:                "cc_library system_shared_libs empty for shared, bionic variant",
1771		ModuleTypeUnderTest:        "cc_library",
1772		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1773		Blueprint: soongCcLibraryPreamble + `
1774cc_library {
1775    name: "shared_empty",
1776    target: {
1777        bionic: {
1778            shared: {
1779                system_shared_libs: [],
1780            }
1781        }
1782    },
1783    include_build_directory: false,
1784}
1785`,
1786		ExpectedBazelTargets: []string{
1787			MakeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
1788			MakeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
1789				"system_dynamic_deps": "[]",
1790			}),
1791		},
1792	})
1793}
1794
1795func TestCcLibrary_SystemSharedLibsLinuxBionicEmpty(t *testing.T) {
1796	// Note that this behavior is technically incorrect (it's a simplification).
1797	// The correct behavior would be if bp2build wrote `system_dynamic_deps = []`
1798	// only for linux_bionic, but `android` had `["libc", "libdl", "libm"].
1799	// b/195791252 tracks the fix.
1800	runCcLibraryTestCase(t, Bp2buildTestCase{
1801		Description:                "cc_library system_shared_libs empty for linux_bionic variant",
1802		ModuleTypeUnderTest:        "cc_library",
1803		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1804		Blueprint: soongCcLibraryPreamble + `
1805cc_library {
1806	name: "libc_musl",
1807	bazel_module: { bp2build_available: false },
1808}
1809
1810cc_library {
1811    name: "target_linux_bionic_empty",
1812    target: {
1813        linux_bionic: {
1814            system_shared_libs: [],
1815        },
1816    },
1817    include_build_directory: false,
1818}
1819`,
1820		ExpectedBazelTargets: makeCcLibraryTargets("target_linux_bionic_empty", AttrNameToString{
1821			"system_dynamic_deps": `select({
1822        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1823        "//conditions:default": [],
1824    })`,
1825		}),
1826	},
1827	)
1828}
1829
1830func TestCcLibrary_SystemSharedLibsBionicEmpty(t *testing.T) {
1831	runCcLibraryTestCase(t, Bp2buildTestCase{
1832		Description:                "cc_library system_shared_libs empty for bionic variant",
1833		ModuleTypeUnderTest:        "cc_library",
1834		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1835		Blueprint: soongCcLibraryPreamble + `
1836cc_library {
1837	name: "libc_musl",
1838	bazel_module: { bp2build_available: false },
1839}
1840
1841cc_library {
1842    name: "target_bionic_empty",
1843    target: {
1844        bionic: {
1845            system_shared_libs: [],
1846        },
1847    },
1848    include_build_directory: false,
1849}
1850`,
1851		ExpectedBazelTargets: makeCcLibraryTargets("target_bionic_empty", AttrNameToString{
1852			"system_dynamic_deps": `select({
1853        "//build/bazel/platforms/os:linux_musl": [":libc_musl"],
1854        "//conditions:default": [],
1855    })`,
1856		}),
1857	},
1858	)
1859}
1860
1861func TestCcLibrary_SystemSharedLibsMuslEmpty(t *testing.T) {
1862	runCcLibraryTestCase(t, Bp2buildTestCase{
1863		Description:                "cc_library system_shared_lib empty for musl variant",
1864		ModuleTypeUnderTest:        "cc_library",
1865		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1866		Blueprint: soongCcLibraryPreamble + `
1867cc_library {
1868		name: "libc_musl",
1869		bazel_module: { bp2build_available: false },
1870}
1871
1872cc_library {
1873    name: "target_musl_empty",
1874    target: {
1875        musl: {
1876            system_shared_libs: [],
1877        },
1878    },
1879    include_build_directory: false,
1880}
1881`,
1882		ExpectedBazelTargets: makeCcLibraryTargets("target_musl_empty", AttrNameToString{
1883			"system_dynamic_deps": `[]`,
1884		}),
1885	})
1886}
1887
1888func TestCcLibrary_SystemSharedLibsLinuxMuslEmpty(t *testing.T) {
1889	runCcLibraryTestCase(t, Bp2buildTestCase{
1890		Description:                "cc_library system_shared_lib empty for linux_musl variant",
1891		ModuleTypeUnderTest:        "cc_library",
1892		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1893		Blueprint: soongCcLibraryPreamble + `
1894cc_library {
1895		name: "libc_musl",
1896		bazel_module: { bp2build_available: false },
1897}
1898
1899cc_library {
1900    name: "target_linux_musl_empty",
1901    target: {
1902        linux_musl: {
1903            system_shared_libs: [],
1904        },
1905    },
1906    include_build_directory: false,
1907}
1908`,
1909		ExpectedBazelTargets: makeCcLibraryTargets("target_linux_musl_empty", AttrNameToString{
1910			"system_dynamic_deps": `[]`,
1911		}),
1912	})
1913}
1914func TestCcLibrary_SystemSharedLibsSharedAndRoot(t *testing.T) {
1915	runCcLibraryTestCase(t, Bp2buildTestCase{
1916		Description:                "cc_library system_shared_libs set for shared and root",
1917		ModuleTypeUnderTest:        "cc_library",
1918		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1919		Blueprint: soongCcLibraryPreamble + `
1920cc_library {
1921    name: "libc",
1922    bazel_module: { bp2build_available: false },
1923}
1924cc_library {
1925    name: "libm",
1926    bazel_module: { bp2build_available: false },
1927}
1928
1929cc_library {
1930    name: "foo",
1931    system_shared_libs: ["libc"],
1932    shared: {
1933        system_shared_libs: ["libm"],
1934    },
1935    include_build_directory: false,
1936}
1937`,
1938		ExpectedBazelTargets: []string{
1939			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
1940				"system_dynamic_deps": `[":libc"]`,
1941			}),
1942			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1943				"system_dynamic_deps": `[
1944        ":libc",
1945        ":libm",
1946    ]`,
1947			}),
1948		},
1949	})
1950}
1951
1952func TestCcLibraryOsSelects(t *testing.T) {
1953	runCcLibraryTestCase(t, Bp2buildTestCase{
1954		Description:                "cc_library - selects for all os targets",
1955		ModuleTypeUnderTest:        "cc_library",
1956		ModuleTypeUnderTestFactory: cc.LibraryFactory,
1957		Filesystem:                 map[string]string{},
1958		Blueprint: soongCcLibraryPreamble + `
1959cc_library {
1960    name: "foo-lib",
1961    srcs: ["base.cpp"],
1962    target: {
1963        android: {
1964            srcs: ["android.cpp"],
1965        },
1966        linux: {
1967            srcs: ["linux.cpp"],
1968        },
1969        linux_glibc: {
1970            srcs: ["linux_glibc.cpp"],
1971        },
1972        darwin: {
1973            srcs: ["darwin.cpp"],
1974        },
1975        bionic: {
1976            srcs: ["bionic.cpp"],
1977        },
1978        linux_musl: {
1979            srcs: ["linux_musl.cpp"],
1980        },
1981        windows: {
1982            srcs: ["windows.cpp"],
1983        },
1984    },
1985    include_build_directory: false,
1986}
1987`,
1988		ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
1989			"srcs": `["base.cpp"] + select({
1990        "//build/bazel/platforms/os:android": [
1991            "linux.cpp",
1992            "bionic.cpp",
1993            "android.cpp",
1994        ],
1995        "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
1996        "//build/bazel/platforms/os:linux_bionic": [
1997            "linux.cpp",
1998            "bionic.cpp",
1999        ],
2000        "//build/bazel/platforms/os:linux_glibc": [
2001            "linux.cpp",
2002            "linux_glibc.cpp",
2003        ],
2004        "//build/bazel/platforms/os:linux_musl": [
2005            "linux.cpp",
2006            "linux_musl.cpp",
2007        ],
2008        "//build/bazel/platforms/os:windows": ["windows.cpp"],
2009        "//conditions:default": [],
2010    })`,
2011		}),
2012	},
2013	)
2014}
2015
2016func TestLibcryptoHashInjection(t *testing.T) {
2017	runCcLibraryTestCase(t, Bp2buildTestCase{
2018		Description:                "cc_library - libcrypto hash injection",
2019		ModuleTypeUnderTest:        "cc_library",
2020		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2021		Filesystem:                 map[string]string{},
2022		Blueprint: soongCcLibraryPreamble + `
2023cc_library {
2024    name: "libcrypto",
2025    target: {
2026        android: {
2027            inject_bssl_hash: true,
2028        },
2029    },
2030    include_build_directory: false,
2031}
2032`,
2033		ExpectedBazelTargets: makeCcLibraryTargets("libcrypto", AttrNameToString{
2034			"inject_bssl_hash": `select({
2035        "//build/bazel/platforms/os:android": True,
2036        "//conditions:default": None,
2037    })`,
2038		}),
2039	},
2040	)
2041}
2042
2043func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) {
2044	type testCase struct {
2045		cpp_std        string
2046		c_std          string
2047		gnu_extensions string
2048		bazel_cpp_std  string
2049		bazel_c_std    string
2050	}
2051
2052	testCases := []testCase{
2053		// Existing usages of cpp_std in AOSP are:
2054		// experimental, c++11, c++17, c++2a, c++98, gnu++11, gnu++17
2055		//
2056		// not set, only emit if gnu_extensions is disabled. the default (gnu+17
2057		// is set in the toolchain.)
2058		{cpp_std: "", gnu_extensions: "", bazel_cpp_std: ""},
2059		{cpp_std: "", gnu_extensions: "false", bazel_cpp_std: "cpp_std_default_no_gnu", bazel_c_std: "c_std_default_no_gnu"},
2060		{cpp_std: "", gnu_extensions: "true", bazel_cpp_std: ""},
2061		// experimental defaults to gnu++2a
2062		{cpp_std: "experimental", gnu_extensions: "", bazel_cpp_std: "cpp_std_experimental"},
2063		{cpp_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "cpp_std_experimental_no_gnu", bazel_c_std: "c_std_default_no_gnu"},
2064		{cpp_std: "experimental", gnu_extensions: "true", bazel_cpp_std: "cpp_std_experimental"},
2065		// Explicitly setting a c++ std does not use replace gnu++ std even if
2066		// gnu_extensions is true.
2067		// "c++11",
2068		{cpp_std: "c++11", gnu_extensions: "", bazel_cpp_std: "c++11"},
2069		{cpp_std: "c++11", gnu_extensions: "false", bazel_cpp_std: "c++11", bazel_c_std: "c_std_default_no_gnu"},
2070		{cpp_std: "c++11", gnu_extensions: "true", bazel_cpp_std: "c++11"},
2071		// "c++17",
2072		{cpp_std: "c++17", gnu_extensions: "", bazel_cpp_std: "c++17"},
2073		{cpp_std: "c++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c_std_default_no_gnu"},
2074		{cpp_std: "c++17", gnu_extensions: "true", bazel_cpp_std: "c++17"},
2075		// "c++2a",
2076		{cpp_std: "c++2a", gnu_extensions: "", bazel_cpp_std: "c++2a"},
2077		{cpp_std: "c++2a", gnu_extensions: "false", bazel_cpp_std: "c++2a", bazel_c_std: "c_std_default_no_gnu"},
2078		{cpp_std: "c++2a", gnu_extensions: "true", bazel_cpp_std: "c++2a"},
2079		// "c++98",
2080		{cpp_std: "c++98", gnu_extensions: "", bazel_cpp_std: "c++98"},
2081		{cpp_std: "c++98", gnu_extensions: "false", bazel_cpp_std: "c++98", bazel_c_std: "c_std_default_no_gnu"},
2082		{cpp_std: "c++98", gnu_extensions: "true", bazel_cpp_std: "c++98"},
2083		// gnu++ is replaced with c++ if gnu_extensions is explicitly false.
2084		// "gnu++11",
2085		{cpp_std: "gnu++11", gnu_extensions: "", bazel_cpp_std: "gnu++11"},
2086		{cpp_std: "gnu++11", gnu_extensions: "false", bazel_cpp_std: "c++11", bazel_c_std: "c_std_default_no_gnu"},
2087		{cpp_std: "gnu++11", gnu_extensions: "true", bazel_cpp_std: "gnu++11"},
2088		// "gnu++17",
2089		{cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17"},
2090		{cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c_std_default_no_gnu"},
2091		{cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17"},
2092
2093		// some c_std test cases
2094		{c_std: "experimental", gnu_extensions: "", bazel_c_std: "c_std_experimental"},
2095		{c_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "cpp_std_default_no_gnu", bazel_c_std: "c_std_experimental_no_gnu"},
2096		{c_std: "experimental", gnu_extensions: "true", bazel_c_std: "c_std_experimental"},
2097		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17", bazel_c_std: "gnu11"},
2098		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c11"},
2099		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17", bazel_c_std: "gnu11"},
2100	}
2101	for i, tc := range testCases {
2102		name := fmt.Sprintf("cpp std: %q, c std: %q, gnu_extensions: %q", tc.cpp_std, tc.c_std, tc.gnu_extensions)
2103		t.Run(name, func(t *testing.T) {
2104			name_prefix := fmt.Sprintf("a_%v", i)
2105			cppStdProp := ""
2106			if tc.cpp_std != "" {
2107				cppStdProp = fmt.Sprintf("    cpp_std: \"%s\",", tc.cpp_std)
2108			}
2109			cStdProp := ""
2110			if tc.c_std != "" {
2111				cStdProp = fmt.Sprintf("    c_std: \"%s\",", tc.c_std)
2112			}
2113			gnuExtensionsProp := ""
2114			if tc.gnu_extensions != "" {
2115				gnuExtensionsProp = fmt.Sprintf("    gnu_extensions: %s,", tc.gnu_extensions)
2116			}
2117			attrs := AttrNameToString{}
2118			if tc.bazel_cpp_std != "" {
2119				attrs["cpp_std"] = fmt.Sprintf(`"%s"`, tc.bazel_cpp_std)
2120			}
2121			if tc.bazel_c_std != "" {
2122				attrs["c_std"] = fmt.Sprintf(`"%s"`, tc.bazel_c_std)
2123			}
2124
2125			runCcLibraryTestCase(t, Bp2buildTestCase{
2126				Description: fmt.Sprintf(
2127					"cc_library with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
2128				ModuleTypeUnderTest:        "cc_library",
2129				ModuleTypeUnderTestFactory: cc.LibraryFactory,
2130				Blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
2131cc_library {
2132	name: "%s_full",
2133%s // cpp_std: *string
2134%s // c_std: *string
2135%s // gnu_extensions: *bool
2136	include_build_directory: false,
2137}
2138`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
2139				ExpectedBazelTargets: makeCcLibraryTargets(name_prefix+"_full", attrs),
2140			})
2141
2142			runCcLibraryStaticTestCase(t, Bp2buildTestCase{
2143				Description: fmt.Sprintf(
2144					"cc_library_static with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
2145				ModuleTypeUnderTest:        "cc_library_static",
2146				ModuleTypeUnderTestFactory: cc.LibraryStaticFactory,
2147				Blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
2148cc_library_static {
2149	name: "%s_static",
2150%s // cpp_std: *string
2151%s // c_std: *string
2152%s // gnu_extensions: *bool
2153	include_build_directory: false,
2154}
2155`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
2156				ExpectedBazelTargets: []string{
2157					MakeBazelTarget("cc_library_static", name_prefix+"_static", attrs),
2158				},
2159			})
2160
2161			runCcLibrarySharedTestCase(t, Bp2buildTestCase{
2162				Description: fmt.Sprintf(
2163					"cc_library_shared with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
2164				ModuleTypeUnderTest:        "cc_library_shared",
2165				ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
2166				Blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
2167cc_library_shared {
2168	name: "%s_shared",
2169%s // cpp_std: *string
2170%s // c_std: *string
2171%s // gnu_extensions: *bool
2172	include_build_directory: false,
2173}
2174`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
2175				ExpectedBazelTargets: []string{
2176					MakeBazelTarget("cc_library_shared", name_prefix+"_shared", attrs),
2177				},
2178			})
2179		})
2180	}
2181}
2182
2183func TestCcLibraryProtoSimple(t *testing.T) {
2184	runCcLibraryTestCase(t, Bp2buildTestCase{
2185		ModuleTypeUnderTest:        "cc_library",
2186		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2187		Blueprint: soongCcProtoPreamble + `cc_library {
2188	name: "foo",
2189	srcs: ["foo.proto"],
2190	include_build_directory: false,
2191}`,
2192		ExpectedBazelTargets: []string{
2193			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2194				"srcs": `["foo.proto"]`,
2195			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2196				"deps": `[":foo_proto"]`,
2197			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2198				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2199				"deps":                              `[":libprotobuf-cpp-lite"]`,
2200			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2201				"dynamic_deps":                      `[":libprotobuf-cpp-lite"]`,
2202				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2203			}),
2204		},
2205	})
2206}
2207
2208func TestCcLibraryProtoNoCanonicalPathFromRoot(t *testing.T) {
2209	runCcLibraryTestCase(t, Bp2buildTestCase{
2210		ModuleTypeUnderTest:        "cc_library",
2211		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2212		Blueprint: soongCcProtoPreamble + `cc_library {
2213	name: "foo",
2214	srcs: ["foo.proto"],
2215	proto: { canonical_path_from_root: false},
2216	include_build_directory: false,
2217}`,
2218		ExpectedBazelTargets: []string{
2219			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2220				"srcs":                `["foo.proto"]`,
2221				"strip_import_prefix": `""`,
2222			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2223				"deps": `[":foo_proto"]`,
2224			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2225				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2226				"deps":                              `[":libprotobuf-cpp-lite"]`,
2227			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2228				"dynamic_deps":                      `[":libprotobuf-cpp-lite"]`,
2229				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2230			}),
2231		},
2232	})
2233}
2234
2235func TestCcLibraryProtoExplicitCanonicalPathFromRoot(t *testing.T) {
2236	runCcLibraryTestCase(t, Bp2buildTestCase{
2237		ModuleTypeUnderTest:        "cc_library",
2238		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2239		Blueprint: soongCcProtoPreamble + `cc_library {
2240	name: "foo",
2241	srcs: ["foo.proto"],
2242	proto: { canonical_path_from_root: true},
2243	include_build_directory: false,
2244}`,
2245		ExpectedBazelTargets: []string{
2246			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2247				"srcs": `["foo.proto"]`,
2248			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2249				"deps": `[":foo_proto"]`,
2250			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2251				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2252				"deps":                              `[":libprotobuf-cpp-lite"]`,
2253			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2254				"dynamic_deps":                      `[":libprotobuf-cpp-lite"]`,
2255				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2256			}),
2257		},
2258	})
2259}
2260
2261func TestCcLibraryProtoFull(t *testing.T) {
2262	runCcLibraryTestCase(t, Bp2buildTestCase{
2263		ModuleTypeUnderTest:        "cc_library",
2264		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2265		Blueprint: soongCcProtoPreamble + `cc_library {
2266	name: "foo",
2267	srcs: ["foo.proto"],
2268	proto: {
2269		type: "full",
2270	},
2271	include_build_directory: false,
2272}`,
2273		ExpectedBazelTargets: []string{
2274			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2275				"srcs": `["foo.proto"]`,
2276			}), MakeBazelTarget("cc_proto_library", "foo_cc_proto", AttrNameToString{
2277				"deps": `[":foo_proto"]`,
2278			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2279				"implementation_whole_archive_deps": `[":foo_cc_proto"]`,
2280				"deps":                              `[":libprotobuf-cpp-full"]`,
2281			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2282				"dynamic_deps":                      `[":libprotobuf-cpp-full"]`,
2283				"implementation_whole_archive_deps": `[":foo_cc_proto"]`,
2284			}),
2285		},
2286	})
2287}
2288
2289func TestCcLibraryProtoLite(t *testing.T) {
2290	runCcLibraryTestCase(t, Bp2buildTestCase{
2291		ModuleTypeUnderTest:        "cc_library",
2292		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2293		Blueprint: soongCcProtoPreamble + `cc_library {
2294	name: "foo",
2295	srcs: ["foo.proto"],
2296	proto: {
2297		type: "lite",
2298	},
2299	include_build_directory: false,
2300}`,
2301		ExpectedBazelTargets: []string{
2302			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2303				"srcs": `["foo.proto"]`,
2304			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2305				"deps": `[":foo_proto"]`,
2306			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2307				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2308				"deps":                              `[":libprotobuf-cpp-lite"]`,
2309			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2310				"dynamic_deps":                      `[":libprotobuf-cpp-lite"]`,
2311				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2312			}),
2313		},
2314	})
2315}
2316
2317func TestCcLibraryProtoExportHeaders(t *testing.T) {
2318	runCcLibraryTestCase(t, Bp2buildTestCase{
2319		ModuleTypeUnderTest:        "cc_library",
2320		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2321		Blueprint: soongCcProtoPreamble + `cc_library {
2322	name: "foo",
2323	srcs: ["foo.proto"],
2324	proto: {
2325		export_proto_headers: true,
2326	},
2327	include_build_directory: false,
2328}`,
2329		ExpectedBazelTargets: []string{
2330			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2331				"srcs": `["foo.proto"]`,
2332			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2333				"deps": `[":foo_proto"]`,
2334			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2335				"deps":               `[":libprotobuf-cpp-lite"]`,
2336				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
2337			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2338				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2339				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
2340			}),
2341		},
2342	})
2343}
2344
2345func TestCcLibraryProtoIncludeDirs(t *testing.T) {
2346	runCcLibraryTestCase(t, Bp2buildTestCase{
2347		ModuleTypeUnderTest:        "cc_library",
2348		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2349		Blueprint: soongCcProtoPreamble + `cc_library {
2350	name: "foo",
2351	srcs: ["foo.proto"],
2352	proto: {
2353		include_dirs: ["external/protobuf/src"],
2354	},
2355	include_build_directory: false,
2356}`,
2357		ExpectedBazelTargets: []string{
2358			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
2359				"srcs": `["foo.proto"]`,
2360				"deps": `["//external/protobuf:libprotobuf-proto"]`,
2361			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
2362				"deps": `[":foo_proto"]`,
2363			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2364				"deps":                              `[":libprotobuf-cpp-lite"]`,
2365				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2366			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2367				"dynamic_deps":                      `[":libprotobuf-cpp-lite"]`,
2368				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
2369			}),
2370		},
2371	})
2372}
2373
2374func TestCcLibraryProtoIncludeDirsUnknown(t *testing.T) {
2375	runCcLibraryTestCase(t, Bp2buildTestCase{
2376		ModuleTypeUnderTest:        "cc_library",
2377		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2378		Blueprint: soongCcProtoPreamble + `cc_library {
2379	name: "foo",
2380	srcs: ["foo.proto"],
2381	proto: {
2382		include_dirs: ["external/protobuf/abc"],
2383	},
2384	include_build_directory: false,
2385}`,
2386		ExpectedErr: fmt.Errorf("module \"foo\": Could not find the proto_library target for include dir: external/protobuf/abc"),
2387	})
2388}
2389
2390func TestCcLibraryConvertedProtoFilegroups(t *testing.T) {
2391	runCcLibraryTestCase(t, Bp2buildTestCase{
2392		ModuleTypeUnderTest:        "cc_library",
2393		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2394		Blueprint: soongCcProtoPreamble + `
2395filegroup {
2396	name: "a_fg_proto",
2397	srcs: ["a_fg.proto"],
2398}
2399
2400cc_library {
2401	name: "a",
2402	srcs: [
2403    ":a_fg_proto",
2404    "a.proto",
2405  ],
2406	proto: {
2407		export_proto_headers: true,
2408	},
2409	include_build_directory: false,
2410}`,
2411		ExpectedBazelTargets: []string{
2412			MakeBazelTarget("proto_library", "a_proto", AttrNameToString{
2413				"deps": `[":a_fg_proto_bp2build_converted"]`,
2414				"srcs": `["a.proto"]`,
2415			}), MakeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
2416				"deps": `[
2417        ":a_fg_proto_bp2build_converted",
2418        ":a_proto",
2419    ]`,
2420			}), MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
2421				"deps":               `[":libprotobuf-cpp-lite"]`,
2422				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2423			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
2424				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2425				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2426			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
2427				"srcs": `["a_fg.proto"]`,
2428				"tags": `[
2429        "apex_available=//apex_available:anyapex",
2430        "manual",
2431    ]`,
2432			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
2433				"srcs": `["a_fg.proto"]`,
2434			}),
2435		},
2436	})
2437}
2438
2439func TestCcLibraryConvertedProtoFilegroupsNoProtoFiles(t *testing.T) {
2440	runCcLibraryTestCase(t, Bp2buildTestCase{
2441		ModuleTypeUnderTest:        "cc_library",
2442		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2443		Blueprint: soongCcProtoPreamble + `
2444filegroup {
2445	name: "a_fg_proto",
2446	srcs: ["a_fg.proto"],
2447}
2448
2449cc_library {
2450	name: "a",
2451	srcs: [
2452    ":a_fg_proto",
2453  ],
2454	proto: {
2455		export_proto_headers: true,
2456	},
2457	include_build_directory: false,
2458}`,
2459		ExpectedBazelTargets: []string{
2460			MakeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
2461				"deps": `[":a_fg_proto_bp2build_converted"]`,
2462			}), MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
2463				"deps":               `[":libprotobuf-cpp-lite"]`,
2464				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2465			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
2466				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2467				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2468			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
2469				"srcs": `["a_fg.proto"]`,
2470				"tags": `[
2471        "apex_available=//apex_available:anyapex",
2472        "manual",
2473    ]`,
2474			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
2475				"srcs": `["a_fg.proto"]`,
2476			}),
2477		},
2478	})
2479}
2480
2481func TestCcLibraryExternalConvertedProtoFilegroups(t *testing.T) {
2482	runCcLibraryTestCase(t, Bp2buildTestCase{
2483		ModuleTypeUnderTest:        "cc_library",
2484		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2485		Filesystem: map[string]string{
2486			"path/to/A/Android.bp": `
2487filegroup {
2488	name: "a_fg_proto",
2489	srcs: ["a_fg.proto"],
2490}`,
2491		},
2492		Blueprint: soongCcProtoPreamble + `
2493cc_library {
2494	name: "a",
2495	srcs: [
2496    ":a_fg_proto",
2497    "a.proto",
2498  ],
2499	proto: {
2500		export_proto_headers: true,
2501	},
2502	include_build_directory: false,
2503}`,
2504		ExpectedBazelTargets: []string{
2505			MakeBazelTarget("proto_library", "a_proto", AttrNameToString{
2506				"deps": `["//path/to/A:a_fg_proto_bp2build_converted"]`,
2507				"srcs": `["a.proto"]`,
2508			}), MakeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
2509				"deps": `[
2510        "//path/to/A:a_fg_proto_bp2build_converted",
2511        ":a_proto",
2512    ]`,
2513			}), MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
2514				"deps":               `[":libprotobuf-cpp-lite"]`,
2515				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2516			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
2517				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2518				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2519			}),
2520		},
2521	})
2522}
2523
2524func TestCcLibraryProtoFilegroups(t *testing.T) {
2525	runCcLibraryTestCase(t, Bp2buildTestCase{
2526		ModuleTypeUnderTest:        "cc_library",
2527		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2528		Blueprint: soongCcProtoPreamble +
2529			simpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") +
2530			simpleModuleDoNotConvertBp2build("filegroup", "b_protos") +
2531			simpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") +
2532			simpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + `
2533cc_library {
2534	name: "a",
2535	srcs: [":a_fg_proto"],
2536	proto: {
2537		export_proto_headers: true,
2538	},
2539	include_build_directory: false,
2540}
2541
2542cc_library {
2543	name: "b",
2544	srcs: [":b_protos"],
2545	proto: {
2546		export_proto_headers: true,
2547	},
2548	include_build_directory: false,
2549}
2550
2551cc_library {
2552	name: "c",
2553	srcs: [":c-proto-srcs"],
2554	proto: {
2555		export_proto_headers: true,
2556	},
2557	include_build_directory: false,
2558}
2559
2560cc_library {
2561	name: "d",
2562	srcs: [":proto-srcs-d"],
2563	proto: {
2564		export_proto_headers: true,
2565	},
2566	include_build_directory: false,
2567}`,
2568		ExpectedBazelTargets: []string{
2569			MakeBazelTarget("proto_library", "a_proto", AttrNameToString{
2570				"srcs": `[":a_fg_proto"]`,
2571			}), MakeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
2572				"deps": `[":a_proto"]`,
2573			}), MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
2574				"deps":               `[":libprotobuf-cpp-lite"]`,
2575				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2576				"srcs":               `[":a_fg_proto_cpp_srcs"]`,
2577				"srcs_as":            `[":a_fg_proto_as_srcs"]`,
2578				"srcs_c":             `[":a_fg_proto_c_srcs"]`,
2579			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
2580				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2581				"whole_archive_deps": `[":a_cc_proto_lite"]`,
2582				"srcs":               `[":a_fg_proto_cpp_srcs"]`,
2583				"srcs_as":            `[":a_fg_proto_as_srcs"]`,
2584				"srcs_c":             `[":a_fg_proto_c_srcs"]`,
2585			}), MakeBazelTarget("proto_library", "b_proto", AttrNameToString{
2586				"srcs": `[":b_protos"]`,
2587			}), MakeBazelTarget("cc_lite_proto_library", "b_cc_proto_lite", AttrNameToString{
2588				"deps": `[":b_proto"]`,
2589			}), MakeBazelTarget("cc_library_static", "b_bp2build_cc_library_static", AttrNameToString{
2590				"deps":               `[":libprotobuf-cpp-lite"]`,
2591				"whole_archive_deps": `[":b_cc_proto_lite"]`,
2592				"srcs":               `[":b_protos_cpp_srcs"]`,
2593				"srcs_as":            `[":b_protos_as_srcs"]`,
2594				"srcs_c":             `[":b_protos_c_srcs"]`,
2595			}), MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
2596				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2597				"whole_archive_deps": `[":b_cc_proto_lite"]`,
2598				"srcs":               `[":b_protos_cpp_srcs"]`,
2599				"srcs_as":            `[":b_protos_as_srcs"]`,
2600				"srcs_c":             `[":b_protos_c_srcs"]`,
2601			}), MakeBazelTarget("proto_library", "c_proto", AttrNameToString{
2602				"srcs": `[":c-proto-srcs"]`,
2603			}), MakeBazelTarget("cc_lite_proto_library", "c_cc_proto_lite", AttrNameToString{
2604				"deps": `[":c_proto"]`,
2605			}), MakeBazelTarget("cc_library_static", "c_bp2build_cc_library_static", AttrNameToString{
2606				"deps":               `[":libprotobuf-cpp-lite"]`,
2607				"whole_archive_deps": `[":c_cc_proto_lite"]`,
2608				"srcs":               `[":c-proto-srcs_cpp_srcs"]`,
2609				"srcs_as":            `[":c-proto-srcs_as_srcs"]`,
2610				"srcs_c":             `[":c-proto-srcs_c_srcs"]`,
2611			}), MakeBazelTarget("cc_library_shared", "c", AttrNameToString{
2612				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2613				"whole_archive_deps": `[":c_cc_proto_lite"]`,
2614				"srcs":               `[":c-proto-srcs_cpp_srcs"]`,
2615				"srcs_as":            `[":c-proto-srcs_as_srcs"]`,
2616				"srcs_c":             `[":c-proto-srcs_c_srcs"]`,
2617			}), MakeBazelTarget("proto_library", "d_proto", AttrNameToString{
2618				"srcs": `[":proto-srcs-d"]`,
2619			}), MakeBazelTarget("cc_lite_proto_library", "d_cc_proto_lite", AttrNameToString{
2620				"deps": `[":d_proto"]`,
2621			}), MakeBazelTarget("cc_library_static", "d_bp2build_cc_library_static", AttrNameToString{
2622				"deps":               `[":libprotobuf-cpp-lite"]`,
2623				"whole_archive_deps": `[":d_cc_proto_lite"]`,
2624				"srcs":               `[":proto-srcs-d_cpp_srcs"]`,
2625				"srcs_as":            `[":proto-srcs-d_as_srcs"]`,
2626				"srcs_c":             `[":proto-srcs-d_c_srcs"]`,
2627			}), MakeBazelTarget("cc_library_shared", "d", AttrNameToString{
2628				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
2629				"whole_archive_deps": `[":d_cc_proto_lite"]`,
2630				"srcs":               `[":proto-srcs-d_cpp_srcs"]`,
2631				"srcs_as":            `[":proto-srcs-d_as_srcs"]`,
2632				"srcs_c":             `[":proto-srcs-d_c_srcs"]`,
2633			}),
2634		},
2635	})
2636}
2637
2638func TestCcLibraryDisabledArchAndTarget(t *testing.T) {
2639	runCcLibraryTestCase(t, Bp2buildTestCase{
2640		ModuleTypeUnderTest:        "cc_library",
2641		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2642		Blueprint: soongCcProtoPreamble + `cc_library {
2643	name: "foo",
2644	srcs: ["foo.cpp"],
2645	host_supported: true,
2646	target: {
2647		darwin: {
2648			enabled: false,
2649		},
2650		windows: {
2651			enabled: false,
2652		},
2653		linux_glibc_x86: {
2654			enabled: false,
2655		},
2656	},
2657	include_build_directory: false,
2658}`,
2659		ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{
2660			"srcs": `["foo.cpp"]`,
2661			"target_compatible_with": `select({
2662        "//build/bazel/platforms/os_arch:darwin_arm64": ["@platforms//:incompatible"],
2663        "//build/bazel/platforms/os_arch:darwin_x86_64": ["@platforms//:incompatible"],
2664        "//build/bazel/platforms/os_arch:linux_glibc_x86": ["@platforms//:incompatible"],
2665        "//build/bazel/platforms/os_arch:windows_x86": ["@platforms//:incompatible"],
2666        "//build/bazel/platforms/os_arch:windows_x86_64": ["@platforms//:incompatible"],
2667        "//conditions:default": [],
2668    })`,
2669		}),
2670	})
2671}
2672
2673func TestCcLibraryDisabledArchAndTargetWithDefault(t *testing.T) {
2674	runCcLibraryTestCase(t, Bp2buildTestCase{
2675		ModuleTypeUnderTest:        "cc_library",
2676		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2677		Blueprint: soongCcProtoPreamble + `cc_library {
2678	name: "foo",
2679	srcs: ["foo.cpp"],
2680  enabled: false,
2681	host_supported: true,
2682	target: {
2683		darwin: {
2684			enabled: true,
2685		},
2686		windows: {
2687			enabled: false,
2688		},
2689		linux_glibc_x86: {
2690			enabled: false,
2691		},
2692	},
2693	include_build_directory: false,
2694}`,
2695		ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{
2696			"srcs": `["foo.cpp"]`,
2697			"target_compatible_with": `select({
2698        "//build/bazel/platforms/os_arch:darwin_arm64": [],
2699        "//build/bazel/platforms/os_arch:darwin_x86_64": [],
2700        "//conditions:default": ["@platforms//:incompatible"],
2701    })`,
2702		}),
2703	})
2704}
2705
2706func TestCcLibrarySharedDisabled(t *testing.T) {
2707	runCcLibraryTestCase(t, Bp2buildTestCase{
2708		ModuleTypeUnderTest:        "cc_library",
2709		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2710		Blueprint: soongCcProtoPreamble + `cc_library {
2711	name: "foo",
2712	srcs: ["foo.cpp"],
2713	enabled: false,
2714	shared: {
2715		enabled: true,
2716	},
2717	target: {
2718		android: {
2719			shared: {
2720				enabled: false,
2721			},
2722		}
2723  },
2724	include_build_directory: false,
2725}`,
2726		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2727			"srcs":                   `["foo.cpp"]`,
2728			"target_compatible_with": `["@platforms//:incompatible"]`,
2729		}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2730			"srcs": `["foo.cpp"]`,
2731			"target_compatible_with": `select({
2732        "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
2733        "//conditions:default": [],
2734    })`,
2735		}),
2736		},
2737	})
2738}
2739
2740func TestCcLibraryStaticDisabledForSomeArch(t *testing.T) {
2741	runCcLibraryTestCase(t, Bp2buildTestCase{
2742		ModuleTypeUnderTest:        "cc_library",
2743		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2744		Blueprint: soongCcProtoPreamble + `cc_library {
2745	name: "foo",
2746	host_supported: true,
2747	srcs: ["foo.cpp"],
2748	shared: {
2749		enabled: false
2750	},
2751	target: {
2752		darwin: {
2753			enabled: true,
2754		},
2755		windows: {
2756			enabled: false,
2757		},
2758		linux_glibc_x86: {
2759			shared: {
2760				enabled: true,
2761			},
2762		},
2763	},
2764	include_build_directory: false,
2765}`,
2766		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
2767			"srcs": `["foo.cpp"]`,
2768			"target_compatible_with": `select({
2769        "//build/bazel/platforms/os:windows": ["@platforms//:incompatible"],
2770        "//conditions:default": [],
2771    })`,
2772		}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
2773			"srcs": `["foo.cpp"]`,
2774			"target_compatible_with": `select({
2775        "//build/bazel/platforms/os_arch:darwin_arm64": [],
2776        "//build/bazel/platforms/os_arch:darwin_x86_64": [],
2777        "//build/bazel/platforms/os_arch:linux_glibc_x86": [],
2778        "//conditions:default": ["@platforms//:incompatible"],
2779    })`,
2780		}),
2781		}})
2782}
2783
2784func TestCcLibraryStubs(t *testing.T) {
2785	expectedBazelTargets := makeCcLibraryTargets("a", AttrNameToString{
2786		"stubs_symbol_file": `"a.map.txt"`,
2787	})
2788	expectedBazelTargets = append(expectedBazelTargets, makeCcStubSuiteTargets("a", AttrNameToString{
2789		"soname":               `"a.so"`,
2790		"source_library_label": `"//foo/bar:a"`,
2791		"stubs_symbol_file":    `"a.map.txt"`,
2792		"stubs_versions": `[
2793        "28",
2794        "29",
2795        "current",
2796    ]`,
2797	}))
2798	runCcLibraryTestCase(t, Bp2buildTestCase{
2799		Description:                "cc_library stubs",
2800		ModuleTypeUnderTest:        "cc_library",
2801		ModuleTypeUnderTestFactory: cc.LibraryFactory,
2802		Dir:                        "foo/bar",
2803		Filesystem: map[string]string{
2804			"foo/bar/Android.bp": `
2805cc_library {
2806    name: "a",
2807    stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
2808    bazel_module: { bp2build_available: true },
2809    include_build_directory: false,
2810}
2811`,
2812		},
2813		Blueprint:            soongCcLibraryPreamble,
2814		ExpectedBazelTargets: expectedBazelTargets,
2815	},
2816	)
2817}
2818
2819func TestCcApiContributionsWithHdrs(t *testing.T) {
2820	bp := `
2821	cc_library {
2822		name: "libfoo",
2823		stubs: { symbol_file: "libfoo.map.txt", versions: ["28", "29", "current"] },
2824		llndk: { symbol_file: "libfoo.map.txt", override_export_include_dirs: ["dir2"]},
2825		export_include_dirs: ["dir1"],
2826	}
2827	`
2828	expectedBazelTargets := []string{
2829		MakeBazelTarget(
2830			"cc_api_library_headers",
2831			"libfoo.module-libapi.headers",
2832			AttrNameToString{
2833				"export_includes": `["dir1"]`,
2834			}),
2835		MakeBazelTarget(
2836			"cc_api_library_headers",
2837			"libfoo.vendorapi.headers",
2838			AttrNameToString{
2839				"export_includes": `["dir2"]`,
2840			}),
2841		MakeBazelTarget(
2842			"cc_api_contribution",
2843			"libfoo.contribution",
2844			AttrNameToString{
2845				"api":          `"libfoo.map.txt"`,
2846				"library_name": `"libfoo"`,
2847				"api_surfaces": `[
2848        "module-libapi",
2849        "vendorapi",
2850    ]`,
2851				"hdrs": `[
2852        ":libfoo.module-libapi.headers",
2853        ":libfoo.vendorapi.headers",
2854    ]`,
2855			}),
2856	}
2857	RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
2858		Blueprint:            bp,
2859		Description:          "cc API contributions to module-libapi and vendorapi",
2860		ExpectedBazelTargets: expectedBazelTargets,
2861	})
2862}
2863
2864func TestCcApiSurfaceCombinations(t *testing.T) {
2865	testCases := []struct {
2866		bp                  string
2867		expectedApi         string
2868		expectedApiSurfaces string
2869		description         string
2870	}{
2871		{
2872			bp: `
2873			cc_library {
2874				name: "a",
2875				stubs: {symbol_file: "a.map.txt"},
2876			}`,
2877			expectedApi:         `"a.map.txt"`,
2878			expectedApiSurfaces: `["module-libapi"]`,
2879			description:         "Library that contributes to module-libapi",
2880		},
2881		{
2882			bp: `
2883			cc_library {
2884				name: "a",
2885				llndk: {symbol_file: "a.map.txt"},
2886			}`,
2887			expectedApi:         `"a.map.txt"`,
2888			expectedApiSurfaces: `["vendorapi"]`,
2889			description:         "Library that contributes to vendorapi",
2890		},
2891		{
2892			bp: `
2893			cc_library {
2894				name: "a",
2895				llndk: {symbol_file: "a.map.txt"},
2896				stubs: {symbol_file: "a.map.txt"},
2897			}`,
2898			expectedApi: `"a.map.txt"`,
2899			expectedApiSurfaces: `[
2900        "module-libapi",
2901        "vendorapi",
2902    ]`,
2903			description: "Library that contributes to module-libapi and vendorapi",
2904		},
2905	}
2906	for _, testCase := range testCases {
2907		expectedBazelTargets := []string{
2908			MakeBazelTarget(
2909				"cc_api_contribution",
2910				"a.contribution",
2911				AttrNameToString{
2912					"library_name": `"a"`,
2913					"hdrs":         `[]`,
2914					"api":          testCase.expectedApi,
2915					"api_surfaces": testCase.expectedApiSurfaces,
2916				},
2917			),
2918		}
2919		RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
2920			Blueprint:            testCase.bp,
2921			Description:          testCase.description,
2922			ExpectedBazelTargets: expectedBazelTargets,
2923		})
2924	}
2925}
2926
2927// llndk struct property in Soong provides users with several options to configure the exported include dirs
2928// Test the generated bazel targets for the different configurations
2929func TestCcVendorApiHeaders(t *testing.T) {
2930	testCases := []struct {
2931		bp                     string
2932		expectedIncludes       string
2933		expectedSystemIncludes string
2934		description            string
2935	}{
2936		{
2937			bp: `
2938			cc_library {
2939				name: "a",
2940				export_include_dirs: ["include"],
2941				export_system_include_dirs: ["base_system_include"],
2942				llndk: {
2943					symbol_file: "a.map.txt",
2944					export_headers_as_system: true,
2945				},
2946			}
2947			`,
2948			expectedIncludes: "",
2949			expectedSystemIncludes: `[
2950        "base_system_include",
2951        "include",
2952    ]`,
2953			description: "Headers are exported as system to API surface",
2954		},
2955		{
2956			bp: `
2957			cc_library {
2958				name: "a",
2959				export_include_dirs: ["include"],
2960				export_system_include_dirs: ["base_system_include"],
2961				llndk: {
2962					symbol_file: "a.map.txt",
2963					override_export_include_dirs: ["llndk_include"],
2964				},
2965			}
2966			`,
2967			expectedIncludes:       `["llndk_include"]`,
2968			expectedSystemIncludes: `["base_system_include"]`,
2969			description:            "Non-system Headers are ovverriden before export to API surface",
2970		},
2971		{
2972			bp: `
2973			cc_library {
2974				name: "a",
2975				export_include_dirs: ["include"],
2976				export_system_include_dirs: ["base_system_include"],
2977				llndk: {
2978					symbol_file: "a.map.txt",
2979					override_export_include_dirs: ["llndk_include"],
2980					export_headers_as_system: true,
2981				},
2982			}
2983			`,
2984			expectedIncludes: "", // includes are set to nil
2985			expectedSystemIncludes: `[
2986        "base_system_include",
2987        "llndk_include",
2988    ]`,
2989			description: "System Headers are extended before export to API surface",
2990		},
2991	}
2992	for _, testCase := range testCases {
2993		attrs := AttrNameToString{}
2994		if testCase.expectedIncludes != "" {
2995			attrs["export_includes"] = testCase.expectedIncludes
2996		}
2997		if testCase.expectedSystemIncludes != "" {
2998			attrs["export_system_includes"] = testCase.expectedSystemIncludes
2999		}
3000
3001		expectedBazelTargets := []string{
3002			MakeBazelTarget("cc_api_library_headers", "a.vendorapi.headers", attrs),
3003			// Create a target for cc_api_contribution target
3004			MakeBazelTarget("cc_api_contribution", "a.contribution", AttrNameToString{
3005				"api":          `"a.map.txt"`,
3006				"api_surfaces": `["vendorapi"]`,
3007				"hdrs":         `[":a.vendorapi.headers"]`,
3008				"library_name": `"a"`,
3009			}),
3010		}
3011		RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
3012			Blueprint:            testCase.bp,
3013			ExpectedBazelTargets: expectedBazelTargets,
3014		})
3015	}
3016}
3017
3018func TestCcLibraryStubsAcrossConfigsDuplicatesRemoved(t *testing.T) {
3019	runCcLibraryTestCase(t, Bp2buildTestCase{
3020		Description:                "stub target generation of the same lib across configs should not result in duplicates",
3021		ModuleTypeUnderTest:        "cc_library",
3022		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3023		Filesystem: map[string]string{
3024			"bar.map.txt": "",
3025		},
3026		Blueprint: `
3027cc_library {
3028	name: "barlib",
3029	stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
3030	bazel_module: { bp2build_available: false },
3031}
3032cc_library {
3033	name: "foolib",
3034	shared_libs: ["barlib"],
3035	target: {
3036		android: {
3037			shared_libs: ["barlib"],
3038		},
3039	},
3040	bazel_module: { bp2build_available: true },
3041	apex_available: ["foo"],
3042}`,
3043		ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
3044			"implementation_dynamic_deps": `select({
3045        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:barlib"],
3046        "//conditions:default": [":barlib"],
3047    })`,
3048			"local_includes": `["."]`,
3049			"tags":           `["apex_available=foo"]`,
3050		}),
3051	})
3052}
3053
3054func TestCcLibraryExcludesLibsHost(t *testing.T) {
3055	runCcLibraryTestCase(t, Bp2buildTestCase{
3056		ModuleTypeUnderTest:        "cc_library",
3057		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3058		Filesystem: map[string]string{
3059			"bar.map.txt": "",
3060		},
3061		Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "bazlib") + `
3062cc_library {
3063	name: "quxlib",
3064	stubs: { symbol_file: "bar.map.txt", versions: ["current"] },
3065	bazel_module: { bp2build_available: false },
3066}
3067cc_library {
3068	name: "barlib",
3069	stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
3070	bazel_module: { bp2build_available: false },
3071}
3072cc_library {
3073	name: "foolib",
3074	shared_libs: ["barlib", "quxlib"],
3075	target: {
3076		host: {
3077			shared_libs: ["bazlib"],
3078			exclude_shared_libs: ["barlib"],
3079		},
3080	},
3081	include_build_directory: false,
3082	bazel_module: { bp2build_available: true },
3083	apex_available: ["foo"],
3084}`,
3085		ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
3086			"implementation_dynamic_deps": `select({
3087        "//build/bazel/platforms/os:darwin": [":bazlib"],
3088        "//build/bazel/platforms/os:linux_bionic": [":bazlib"],
3089        "//build/bazel/platforms/os:linux_glibc": [":bazlib"],
3090        "//build/bazel/platforms/os:linux_musl": [":bazlib"],
3091        "//build/bazel/platforms/os:windows": [":bazlib"],
3092        "//conditions:default": [],
3093    }) + select({
3094        "//build/bazel/platforms/os:darwin": [":quxlib"],
3095        "//build/bazel/platforms/os:linux_bionic": [":quxlib"],
3096        "//build/bazel/platforms/os:linux_glibc": [":quxlib"],
3097        "//build/bazel/platforms/os:linux_musl": [":quxlib"],
3098        "//build/bazel/platforms/os:windows": [":quxlib"],
3099        "//build/bazel/rules/apex:android-in_apex": [
3100            "@api_surfaces//module-libapi/current:barlib",
3101            "@api_surfaces//module-libapi/current:quxlib",
3102        ],
3103        "//conditions:default": [
3104            ":barlib",
3105            ":quxlib",
3106        ],
3107    })`,
3108			"tags": `["apex_available=foo"]`,
3109		}),
3110	})
3111}
3112
3113func TestCcLibraryEscapeLdflags(t *testing.T) {
3114	runCcLibraryTestCase(t, Bp2buildTestCase{
3115		ModuleTypeUnderTest:        "cc_library",
3116		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3117		Blueprint: soongCcProtoPreamble + `cc_library {
3118	name: "foo",
3119	ldflags: ["-Wl,--rpath,${ORIGIN}"],
3120	include_build_directory: false,
3121}`,
3122		ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{
3123			"linkopts": `["-Wl,--rpath,$${ORIGIN}"]`,
3124		}),
3125	})
3126}
3127
3128func TestCcLibraryConvertLex(t *testing.T) {
3129	runCcLibraryTestCase(t, Bp2buildTestCase{
3130		ModuleTypeUnderTest:        "cc_library",
3131		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3132		Filesystem: map[string]string{
3133			"foo.c":   "",
3134			"bar.cc":  "",
3135			"foo1.l":  "",
3136			"bar1.ll": "",
3137			"foo2.l":  "",
3138			"bar2.ll": "",
3139		},
3140		Blueprint: `cc_library {
3141	name: "foo_lib",
3142	srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"],
3143	lex: { flags: ["--foo_flags"] },
3144	include_build_directory: false,
3145	bazel_module: { bp2build_available: true },
3146}`,
3147		ExpectedBazelTargets: append([]string{
3148			MakeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
3149				"srcs": `[
3150        "foo1.l",
3151        "foo2.l",
3152    ]`,
3153				"lexopts": `["--foo_flags"]`,
3154			}),
3155			MakeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
3156				"srcs": `[
3157        "bar1.ll",
3158        "bar2.ll",
3159    ]`,
3160				"lexopts": `["--foo_flags"]`,
3161			}),
3162		},
3163			makeCcLibraryTargets("foo_lib", AttrNameToString{
3164				"srcs": `[
3165        "bar.cc",
3166        ":foo_lib_genlex_ll",
3167    ]`,
3168				"srcs_c": `[
3169        "foo.c",
3170        ":foo_lib_genlex_l",
3171    ]`,
3172			})...),
3173	})
3174}
3175
3176func TestCCLibraryRuntimeDeps(t *testing.T) {
3177	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
3178		Blueprint: `cc_library_shared {
3179	name: "bar",
3180}
3181
3182cc_library {
3183  name: "foo",
3184  runtime_libs: ["foo"],
3185}`,
3186		ExpectedBazelTargets: []string{
3187			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
3188				"local_includes": `["."]`,
3189			}),
3190			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3191				"runtime_deps":   `[":foo"]`,
3192				"local_includes": `["."]`,
3193			}),
3194			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3195				"runtime_deps":   `[":foo"]`,
3196				"local_includes": `["."]`,
3197			}),
3198		},
3199	})
3200}
3201
3202func TestCcLibraryWithInstructionSet(t *testing.T) {
3203	runCcLibraryTestCase(t, Bp2buildTestCase{
3204		ModuleTypeUnderTest:        "cc_library",
3205		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3206		Blueprint: `cc_library {
3207    name: "foo",
3208    arch: {
3209      arm: {
3210        instruction_set: "arm",
3211      }
3212    }
3213}
3214`,
3215		ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{
3216			"features": `select({
3217        "//build/bazel/platforms/arch:arm": [
3218            "arm_isa_arm",
3219            "-arm_isa_thumb",
3220        ],
3221        "//conditions:default": [],
3222    })`,
3223			"local_includes": `["."]`,
3224		}),
3225	})
3226}
3227
3228func TestCcLibraryEmptySuffix(t *testing.T) {
3229	runCcLibraryTestCase(t, Bp2buildTestCase{
3230		Description:                "cc_library with empty suffix",
3231		ModuleTypeUnderTest:        "cc_library",
3232		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3233		Filesystem: map[string]string{
3234			"foo.c": "",
3235		},
3236		Blueprint: `cc_library {
3237    name: "foo",
3238    suffix: "",
3239    srcs: ["foo.c"],
3240    include_build_directory: false,
3241}`,
3242		ExpectedBazelTargets: []string{
3243			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3244				"srcs_c": `["foo.c"]`,
3245			}),
3246			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3247				"srcs_c": `["foo.c"]`,
3248				"suffix": `""`,
3249			}),
3250		},
3251	})
3252}
3253
3254func TestCcLibrarySuffix(t *testing.T) {
3255	runCcLibraryTestCase(t, Bp2buildTestCase{
3256		Description:                "cc_library with suffix",
3257		ModuleTypeUnderTest:        "cc_library",
3258		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3259		Filesystem: map[string]string{
3260			"foo.c": "",
3261		},
3262		Blueprint: `cc_library {
3263    name: "foo",
3264    suffix: "-suf",
3265    srcs: ["foo.c"],
3266    include_build_directory: false,
3267}`,
3268		ExpectedBazelTargets: []string{
3269			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3270				"srcs_c": `["foo.c"]`,
3271			}),
3272			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3273				"srcs_c": `["foo.c"]`,
3274				"suffix": `"-suf"`,
3275			}),
3276		},
3277	})
3278}
3279
3280func TestCcLibraryArchVariantSuffix(t *testing.T) {
3281	runCcLibraryTestCase(t, Bp2buildTestCase{
3282		Description:                "cc_library with arch-variant suffix",
3283		ModuleTypeUnderTest:        "cc_library",
3284		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3285		Filesystem: map[string]string{
3286			"foo.c": "",
3287		},
3288		Blueprint: `cc_library {
3289    name: "foo",
3290    arch: {
3291        arm64: { suffix: "-64" },
3292        arm:   { suffix: "-32" },
3293		},
3294    srcs: ["foo.c"],
3295    include_build_directory: false,
3296}`,
3297		ExpectedBazelTargets: []string{
3298			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3299				"srcs_c": `["foo.c"]`,
3300			}),
3301			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3302				"srcs_c": `["foo.c"]`,
3303				"suffix": `select({
3304        "//build/bazel/platforms/arch:arm": "-32",
3305        "//build/bazel/platforms/arch:arm64": "-64",
3306        "//conditions:default": None,
3307    })`,
3308			}),
3309		},
3310	})
3311}
3312
3313func TestCcLibraryWithAidlSrcs(t *testing.T) {
3314	runCcLibraryTestCase(t, Bp2buildTestCase{
3315		Description:                "cc_library with aidl srcs",
3316		ModuleTypeUnderTest:        "cc_library",
3317		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3318		Blueprint: `
3319filegroup {
3320    name: "A_aidl",
3321    srcs: ["aidl/A.aidl"],
3322	path: "aidl",
3323}
3324cc_library {
3325	name: "foo",
3326	srcs: [
3327		":A_aidl",
3328		"B.aidl",
3329	],
3330}`,
3331		ExpectedBazelTargets: []string{
3332			MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{
3333				"srcs":                `["aidl/A.aidl"]`,
3334				"strip_import_prefix": `"aidl"`,
3335				"tags":                `["apex_available=//apex_available:anyapex"]`,
3336			}),
3337			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
3338				"srcs": `["B.aidl"]`,
3339			}),
3340			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
3341				"deps": `[
3342        ":A_aidl",
3343        ":foo_aidl_library",
3344    ]`,
3345			}),
3346			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3347				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
3348				"local_includes":                    `["."]`,
3349			}),
3350			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3351				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
3352				"local_includes":                    `["."]`,
3353			}),
3354		},
3355	})
3356}
3357
3358func TestCcLibraryWithNonAdjacentAidlFilegroup(t *testing.T) {
3359	runCcLibraryTestCase(t, Bp2buildTestCase{
3360		Description:                "cc_library with non aidl filegroup",
3361		ModuleTypeUnderTest:        "cc_library",
3362		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3363		Filesystem: map[string]string{
3364			"path/to/A/Android.bp": `
3365filegroup {
3366    name: "A_aidl",
3367    srcs: ["aidl/A.aidl"],
3368    path: "aidl",
3369}`,
3370		},
3371		Blueprint: `
3372cc_library {
3373    name: "foo",
3374    srcs: [
3375        ":A_aidl",
3376    ],
3377}`,
3378		ExpectedBazelTargets: []string{
3379			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
3380				"deps": `["//path/to/A:A_aidl"]`,
3381			}),
3382			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3383				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
3384				"local_includes":                    `["."]`,
3385			}),
3386			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3387				"local_includes":                    `["."]`,
3388				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
3389			}),
3390		},
3391	})
3392}
3393
3394func TestCcLibraryWithExportAidlHeaders(t *testing.T) {
3395	runCcLibraryTestCase(t, Bp2buildTestCase{
3396		Description:                "cc_library with export aidl headers",
3397		ModuleTypeUnderTest:        "cc_library",
3398		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3399		Blueprint: `
3400cc_library {
3401    name: "foo",
3402    srcs: [
3403        "Foo.aidl",
3404    ],
3405    aidl: {
3406        export_aidl_headers: true,
3407    }
3408}`,
3409		ExpectedBazelTargets: []string{
3410			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
3411				"srcs": `["Foo.aidl"]`,
3412			}),
3413			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
3414				"deps": `[":foo_aidl_library"]`,
3415			}),
3416			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3417				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
3418				"local_includes":     `["."]`,
3419			}),
3420			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3421				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
3422				"local_includes":     `["."]`,
3423			}),
3424		},
3425	})
3426}
3427
3428func TestCcLibraryWithTargetApex(t *testing.T) {
3429	runCcLibraryTestCase(t, Bp2buildTestCase{
3430		Description:                "cc_library with target.apex",
3431		ModuleTypeUnderTest:        "cc_library",
3432		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3433		Blueprint: `
3434cc_library {
3435    name: "foo",
3436	shared_libs: ["bar", "baz"],
3437	static_libs: ["baz", "buh"],
3438	target: {
3439        apex: {
3440            exclude_shared_libs: ["bar"],
3441            exclude_static_libs: ["buh"],
3442        }
3443    }
3444}`,
3445		ExpectedBazelTargets: []string{
3446			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3447				"implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
3448        "//build/bazel/rules/apex:in_apex": [],
3449        "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
3450    })`,
3451				"implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
3452        "//build/bazel/rules/apex:in_apex": [],
3453        "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
3454    })`,
3455				"local_includes": `["."]`,
3456			}),
3457			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3458				"implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
3459        "//build/bazel/rules/apex:in_apex": [],
3460        "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
3461    })`,
3462				"implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
3463        "//build/bazel/rules/apex:in_apex": [],
3464        "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
3465    })`,
3466				"local_includes": `["."]`,
3467			}),
3468		},
3469	})
3470}
3471
3472func TestCcLibraryWithTargetApexAndExportLibHeaders(t *testing.T) {
3473	runCcLibraryTestCase(t, Bp2buildTestCase{
3474		Description:                "cc_library with target.apex and export_shared|static_lib_headers",
3475		ModuleTypeUnderTest:        "cc_library",
3476		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3477		Blueprint: `
3478cc_library_static {
3479    name: "foo",
3480	shared_libs: ["bar", "baz"],
3481    static_libs: ["abc"],
3482    export_shared_lib_headers: ["baz"],
3483    export_static_lib_headers: ["abc"],
3484	target: {
3485        apex: {
3486            exclude_shared_libs: ["baz", "bar"],
3487            exclude_static_libs: ["abc"],
3488        }
3489    }
3490}`,
3491		ExpectedBazelTargets: []string{
3492			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
3493				"implementation_dynamic_deps": `select({
3494        "//build/bazel/rules/apex:in_apex": [],
3495        "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
3496    })`,
3497				"dynamic_deps": `select({
3498        "//build/bazel/rules/apex:in_apex": [],
3499        "//conditions:default": [":baz__BP2BUILD__MISSING__DEP"],
3500    })`,
3501				"deps": `select({
3502        "//build/bazel/rules/apex:in_apex": [],
3503        "//conditions:default": [":abc__BP2BUILD__MISSING__DEP"],
3504    })`,
3505				"local_includes": `["."]`,
3506			}),
3507		},
3508	})
3509}
3510
3511func TestCcLibraryWithSyspropSrcs(t *testing.T) {
3512	runCcLibraryTestCase(t, Bp2buildTestCase{
3513		Description:                "cc_library with sysprop sources",
3514		ModuleTypeUnderTest:        "cc_library",
3515		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3516		Blueprint: `
3517cc_library {
3518	name: "foo",
3519	srcs: [
3520		"bar.sysprop",
3521		"baz.sysprop",
3522		"blah.cpp",
3523	],
3524	min_sdk_version: "5",
3525}`,
3526		ExpectedBazelTargets: []string{
3527			MakeBazelTarget("sysprop_library", "foo_sysprop_library", AttrNameToString{
3528				"srcs": `[
3529        "bar.sysprop",
3530        "baz.sysprop",
3531    ]`,
3532			}),
3533			MakeBazelTarget("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
3534				"dep":             `":foo_sysprop_library"`,
3535				"min_sdk_version": `"5"`,
3536			}),
3537			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3538				"srcs":               `["blah.cpp"]`,
3539				"local_includes":     `["."]`,
3540				"min_sdk_version":    `"5"`,
3541				"whole_archive_deps": `[":foo_cc_sysprop_library_static"]`,
3542			}),
3543			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3544				"srcs":               `["blah.cpp"]`,
3545				"local_includes":     `["."]`,
3546				"min_sdk_version":    `"5"`,
3547				"whole_archive_deps": `[":foo_cc_sysprop_library_static"]`,
3548			}),
3549		},
3550	})
3551}
3552
3553func TestCcLibraryWithSyspropSrcsSomeConfigs(t *testing.T) {
3554	runCcLibraryTestCase(t, Bp2buildTestCase{
3555		Description:                "cc_library with sysprop sources in some configs but not others",
3556		ModuleTypeUnderTest:        "cc_library",
3557		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3558		Blueprint: `
3559cc_library {
3560	name: "foo",
3561	host_supported: true,
3562	srcs: [
3563		"blah.cpp",
3564	],
3565	target: {
3566		android: {
3567			srcs: ["bar.sysprop"],
3568		},
3569	},
3570	min_sdk_version: "5",
3571}`,
3572		ExpectedBazelTargets: []string{
3573			MakeBazelTargetNoRestrictions("sysprop_library", "foo_sysprop_library", AttrNameToString{
3574				"srcs": `select({
3575        "//build/bazel/platforms/os:android": ["bar.sysprop"],
3576        "//conditions:default": [],
3577    })`,
3578			}),
3579			MakeBazelTargetNoRestrictions("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
3580				"dep":             `":foo_sysprop_library"`,
3581				"min_sdk_version": `"5"`,
3582			}),
3583			MakeBazelTargetNoRestrictions("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
3584				"srcs":            `["blah.cpp"]`,
3585				"local_includes":  `["."]`,
3586				"min_sdk_version": `"5"`,
3587				"whole_archive_deps": `select({
3588        "//build/bazel/platforms/os:android": [":foo_cc_sysprop_library_static"],
3589        "//conditions:default": [],
3590    })`,
3591			}),
3592			MakeBazelTargetNoRestrictions("cc_library_shared", "foo", AttrNameToString{
3593				"srcs":            `["blah.cpp"]`,
3594				"local_includes":  `["."]`,
3595				"min_sdk_version": `"5"`,
3596				"whole_archive_deps": `select({
3597        "//build/bazel/platforms/os:android": [":foo_cc_sysprop_library_static"],
3598        "//conditions:default": [],
3599    })`,
3600			}),
3601		},
3602	})
3603}
3604
3605func TestCcLibraryWithAidlAndLibs(t *testing.T) {
3606	runCcLibraryTestCase(t, Bp2buildTestCase{
3607		Description:                "cc_aidl_library depends on libs from parent cc_library_static",
3608		ModuleTypeUnderTest:        "cc_library",
3609		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3610		Blueprint: `
3611cc_library_static {
3612	name: "foo",
3613	srcs: [
3614		"Foo.aidl",
3615	],
3616	static_libs: [
3617		"bar-static",
3618		"baz-static",
3619	],
3620	shared_libs: [
3621		"bar-shared",
3622		"baz-shared",
3623	],
3624	export_static_lib_headers: [
3625		"baz-static",
3626	],
3627	export_shared_lib_headers: [
3628		"baz-shared",
3629	],
3630}` +
3631			simpleModuleDoNotConvertBp2build("cc_library_static", "bar-static") +
3632			simpleModuleDoNotConvertBp2build("cc_library_static", "baz-static") +
3633			simpleModuleDoNotConvertBp2build("cc_library", "bar-shared") +
3634			simpleModuleDoNotConvertBp2build("cc_library", "baz-shared"),
3635		ExpectedBazelTargets: []string{
3636			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
3637				"srcs": `["Foo.aidl"]`,
3638			}),
3639			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
3640				"deps": `[":foo_aidl_library"]`,
3641				"implementation_deps": `[
3642        ":baz-static",
3643        ":bar-static",
3644    ]`,
3645				"implementation_dynamic_deps": `[
3646        ":baz-shared",
3647        ":bar-shared",
3648    ]`,
3649			}),
3650			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
3651				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
3652				"deps":                              `[":baz-static"]`,
3653				"implementation_deps":               `[":bar-static"]`,
3654				"dynamic_deps":                      `[":baz-shared"]`,
3655				"implementation_dynamic_deps":       `[":bar-shared"]`,
3656				"local_includes":                    `["."]`,
3657			}),
3658		},
3659	})
3660}
3661
3662func TestCcLibraryWithTidy(t *testing.T) {
3663	runCcLibraryTestCase(t, Bp2buildTestCase{
3664		Description:                "cc_library uses tidy properties",
3665		ModuleTypeUnderTest:        "cc_library",
3666		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3667		Blueprint: `
3668cc_library_static {
3669	name: "foo",
3670	srcs: ["foo.cpp"],
3671}
3672cc_library_static {
3673	name: "foo-no-tidy",
3674	srcs: ["foo.cpp"],
3675	tidy: false,
3676}
3677cc_library_static {
3678	name: "foo-tidy",
3679	srcs: ["foo.cpp"],
3680	tidy: true,
3681	tidy_checks: ["check1", "check2"],
3682	tidy_checks_as_errors: ["check1error", "check2error"],
3683	tidy_disabled_srcs: ["bar.cpp"],
3684	tidy_timeout_srcs: ["baz.cpp"],
3685}`,
3686		ExpectedBazelTargets: []string{
3687			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
3688				"local_includes": `["."]`,
3689				"srcs":           `["foo.cpp"]`,
3690			}),
3691			MakeBazelTarget("cc_library_static", "foo-no-tidy", AttrNameToString{
3692				"local_includes": `["."]`,
3693				"srcs":           `["foo.cpp"]`,
3694				"tidy":           `"never"`,
3695			}),
3696			MakeBazelTarget("cc_library_static", "foo-tidy", AttrNameToString{
3697				"local_includes": `["."]`,
3698				"srcs":           `["foo.cpp"]`,
3699				"tidy":           `"local"`,
3700				"tidy_checks": `[
3701        "check1",
3702        "check2",
3703    ]`,
3704				"tidy_checks_as_errors": `[
3705        "check1error",
3706        "check2error",
3707    ]`,
3708				"tidy_disabled_srcs": `["bar.cpp"]`,
3709				"tidy_timeout_srcs":  `["baz.cpp"]`,
3710			}),
3711		},
3712	})
3713}
3714
3715func TestCcLibraryWithAfdoEnabled(t *testing.T) {
3716	bp := `
3717cc_library {
3718	name: "foo",
3719	afdo: true,
3720	include_build_directory: false,
3721}`
3722
3723	// TODO(b/260714900): Add test case for arch-specific afdo profile
3724	testCases := []struct {
3725		description          string
3726		filesystem           map[string]string
3727		expectedBazelTargets []string
3728	}{
3729		{
3730			description: "cc_library with afdo enabled and existing profile",
3731			filesystem: map[string]string{
3732				"vendor/google_data/pgo_profile/sampling/BUILD":    "",
3733				"vendor/google_data/pgo_profile/sampling/foo.afdo": "",
3734			},
3735			expectedBazelTargets: []string{
3736				MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3737				MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3738					"fdo_profile": `"//vendor/google_data/pgo_profile/sampling:foo"`,
3739				}),
3740			},
3741		},
3742		{
3743			description: "cc_library with afdo enabled and existing profile in AOSP",
3744			filesystem: map[string]string{
3745				"toolchain/pgo-profiles/sampling/BUILD":    "",
3746				"toolchain/pgo-profiles/sampling/foo.afdo": "",
3747			},
3748			expectedBazelTargets: []string{
3749				MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3750				MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3751					"fdo_profile": `"//toolchain/pgo-profiles/sampling:foo"`,
3752				}),
3753			},
3754		},
3755		{
3756			description: "cc_library with afdo enabled but profile filename doesn't match with module name",
3757			filesystem: map[string]string{
3758				"toolchain/pgo-profiles/sampling/BUILD":    "",
3759				"toolchain/pgo-profiles/sampling/bar.afdo": "",
3760			},
3761			expectedBazelTargets: []string{
3762				MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3763				MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
3764			},
3765		},
3766		{
3767			description: "cc_library with afdo enabled but profile doesn't exist",
3768			expectedBazelTargets: []string{
3769				MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3770				MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
3771			},
3772		},
3773		{
3774			description: "cc_library with afdo enabled and existing profile but BUILD file doesn't exist",
3775			filesystem: map[string]string{
3776				"vendor/google_data/pgo_profile/sampling/foo.afdo": "",
3777			},
3778			expectedBazelTargets: []string{
3779				MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3780				MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
3781			},
3782		},
3783	}
3784	for _, testCase := range testCases {
3785		t.Run(testCase.description, func(t *testing.T) {
3786			runCcLibraryTestCase(t, Bp2buildTestCase{
3787				ExpectedBazelTargets:       testCase.expectedBazelTargets,
3788				ModuleTypeUnderTest:        "cc_library",
3789				ModuleTypeUnderTestFactory: cc.LibraryFactory,
3790				Description:                testCase.description,
3791				Blueprint:                  binaryReplacer.Replace(bp),
3792				Filesystem:                 testCase.filesystem,
3793			})
3794		})
3795	}
3796}
3797
3798func TestCcLibraryHeaderAbiChecker(t *testing.T) {
3799	runCcLibraryTestCase(t, Bp2buildTestCase{
3800		Description:                "cc_library with header abi checker",
3801		ModuleTypeUnderTest:        "cc_library",
3802		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3803		Blueprint: `cc_library {
3804    name: "foo",
3805    header_abi_checker: {
3806        enabled: true,
3807        symbol_file: "a.map.txt",
3808        exclude_symbol_versions: [
3809						"29",
3810						"30",
3811				],
3812        exclude_symbol_tags: [
3813						"tag1",
3814						"tag2",
3815				],
3816        check_all_apis: true,
3817        diff_flags: ["-allow-adding-removing-weak-symbols"],
3818    },
3819    include_build_directory: false,
3820}`,
3821		ExpectedBazelTargets: []string{
3822			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
3823			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
3824				"abi_checker_enabled":     `True`,
3825				"abi_checker_symbol_file": `"a.map.txt"`,
3826				"abi_checker_exclude_symbol_versions": `[
3827        "29",
3828        "30",
3829    ]`,
3830				"abi_checker_exclude_symbol_tags": `[
3831        "tag1",
3832        "tag2",
3833    ]`,
3834				"abi_checker_check_all_apis": `True`,
3835				"abi_checker_diff_flags":     `["-allow-adding-removing-weak-symbols"]`,
3836			}),
3837		},
3838	})
3839}
3840
3841func TestCcLibraryApexAvailable(t *testing.T) {
3842	runCcLibraryTestCase(t, Bp2buildTestCase{
3843		Description:                "cc_library apex_available converted to tags",
3844		ModuleTypeUnderTest:        "cc_library",
3845		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3846		Blueprint: soongCcLibraryPreamble + `
3847cc_library {
3848    name: "a",
3849    srcs: ["a.cpp"],
3850    apex_available: ["com.android.foo"],
3851}
3852`,
3853		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
3854			"tags":           `["apex_available=com.android.foo"]`,
3855			"srcs":           `["a.cpp"]`,
3856			"local_includes": `["."]`,
3857		}),
3858	},
3859	)
3860}
3861
3862func TestCcLibraryApexAvailableMultiple(t *testing.T) {
3863	runCcLibraryTestCase(t, Bp2buildTestCase{
3864		Description:                "cc_library apex_available converted to multiple tags",
3865		ModuleTypeUnderTest:        "cc_library",
3866		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3867		Blueprint: soongCcLibraryPreamble + `
3868cc_library {
3869    name: "a",
3870    srcs: ["a.cpp"],
3871    apex_available: ["com.android.foo", "//apex_available:platform", "com.android.bar"],
3872}
3873`,
3874		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
3875			"tags": `[
3876        "apex_available=com.android.foo",
3877        "apex_available=//apex_available:platform",
3878        "apex_available=com.android.bar",
3879    ]`,
3880			"srcs":           `["a.cpp"]`,
3881			"local_includes": `["."]`,
3882		}),
3883	},
3884	)
3885}
3886
3887// Export_include_dirs and Export_system_include_dirs have "variant_prepend" tag.
3888// In bp2build output, variant info(select) should go before general info.
3889// Internal order of the property should be unchanged. (e.g. ["eid1", "eid2"])
3890func TestCcLibraryVariantPrependPropOrder(t *testing.T) {
3891	runCcLibraryTestCase(t, Bp2buildTestCase{
3892		Description:                "cc_library variant prepend properties order",
3893		ModuleTypeUnderTest:        "cc_library",
3894		ModuleTypeUnderTestFactory: cc.LibraryFactory,
3895		Blueprint: soongCcLibraryPreamble + `
3896cc_library {
3897  name: "a",
3898  srcs: ["a.cpp"],
3899  export_include_dirs: ["eid1", "eid2"],
3900  export_system_include_dirs: ["esid1", "esid2"],
3901    target: {
3902      android: {
3903        export_include_dirs: ["android_eid1", "android_eid2"],
3904        export_system_include_dirs: ["android_esid1", "android_esid2"],
3905      },
3906      android_arm: {
3907        export_include_dirs: ["android_arm_eid1", "android_arm_eid2"],
3908        export_system_include_dirs: ["android_arm_esid1", "android_arm_esid2"],
3909      },
3910      linux: {
3911        export_include_dirs: ["linux_eid1", "linux_eid2"],
3912        export_system_include_dirs: ["linux_esid1", "linux_esid2"],
3913      },
3914    },
3915    multilib: {
3916      lib32: {
3917        export_include_dirs: ["lib32_eid1", "lib32_eid2"],
3918        export_system_include_dirs: ["lib32_esid1", "lib32_esid2"],
3919      },
3920    },
3921    arch: {
3922      arm: {
3923        export_include_dirs: ["arm_eid1", "arm_eid2"],
3924        export_system_include_dirs: ["arm_esid1", "arm_esid2"],
3925      },
3926    }
3927}
3928`,
3929		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
3930			"export_includes": `select({
3931        "//build/bazel/platforms/os_arch:android_arm": [
3932            "android_arm_eid1",
3933            "android_arm_eid2",
3934        ],
3935        "//conditions:default": [],
3936    }) + select({
3937        "//build/bazel/platforms/os:android": [
3938            "android_eid1",
3939            "android_eid2",
3940            "linux_eid1",
3941            "linux_eid2",
3942        ],
3943        "//build/bazel/platforms/os:linux_bionic": [
3944            "linux_eid1",
3945            "linux_eid2",
3946        ],
3947        "//build/bazel/platforms/os:linux_glibc": [
3948            "linux_eid1",
3949            "linux_eid2",
3950        ],
3951        "//build/bazel/platforms/os:linux_musl": [
3952            "linux_eid1",
3953            "linux_eid2",
3954        ],
3955        "//conditions:default": [],
3956    }) + select({
3957        "//build/bazel/platforms/arch:arm": [
3958            "lib32_eid1",
3959            "lib32_eid2",
3960            "arm_eid1",
3961            "arm_eid2",
3962        ],
3963        "//build/bazel/platforms/arch:x86": [
3964            "lib32_eid1",
3965            "lib32_eid2",
3966        ],
3967        "//conditions:default": [],
3968    }) + [
3969        "eid1",
3970        "eid2",
3971    ]`,
3972			"export_system_includes": `select({
3973        "//build/bazel/platforms/os_arch:android_arm": [
3974            "android_arm_esid1",
3975            "android_arm_esid2",
3976        ],
3977        "//conditions:default": [],
3978    }) + select({
3979        "//build/bazel/platforms/os:android": [
3980            "android_esid1",
3981            "android_esid2",
3982            "linux_esid1",
3983            "linux_esid2",
3984        ],
3985        "//build/bazel/platforms/os:linux_bionic": [
3986            "linux_esid1",
3987            "linux_esid2",
3988        ],
3989        "//build/bazel/platforms/os:linux_glibc": [
3990            "linux_esid1",
3991            "linux_esid2",
3992        ],
3993        "//build/bazel/platforms/os:linux_musl": [
3994            "linux_esid1",
3995            "linux_esid2",
3996        ],
3997        "//conditions:default": [],
3998    }) + select({
3999        "//build/bazel/platforms/arch:arm": [
4000            "lib32_esid1",
4001            "lib32_esid2",
4002            "arm_esid1",
4003            "arm_esid2",
4004        ],
4005        "//build/bazel/platforms/arch:x86": [
4006            "lib32_esid1",
4007            "lib32_esid2",
4008        ],
4009        "//conditions:default": [],
4010    }) + [
4011        "esid1",
4012        "esid2",
4013    ]`,
4014			"srcs":                   `["a.cpp"]`,
4015			"local_includes":         `["."]`,
4016			"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
4017		}),
4018	},
4019	)
4020}
4021
4022func TestCcLibraryWithIntegerOverflowProperty(t *testing.T) {
4023	runCcLibraryTestCase(t, Bp2buildTestCase{
4024		Description:                "cc_library has correct features when integer_overflow property is provided",
4025		ModuleTypeUnderTest:        "cc_library",
4026		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4027		Blueprint: `
4028cc_library {
4029		name: "foo",
4030		sanitize: {
4031				integer_overflow: true,
4032		},
4033}
4034`,
4035		ExpectedBazelTargets: []string{
4036			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4037				"features":       `["ubsan_integer_overflow"]`,
4038				"local_includes": `["."]`,
4039			}),
4040			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4041				"features":       `["ubsan_integer_overflow"]`,
4042				"local_includes": `["."]`,
4043			}),
4044		},
4045	})
4046}
4047
4048func TestCcLibraryWithMiscUndefinedProperty(t *testing.T) {
4049	runCcLibraryTestCase(t, Bp2buildTestCase{
4050		Description:                "cc_library has correct features when misc_undefined property is provided",
4051		ModuleTypeUnderTest:        "cc_library",
4052		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4053		Blueprint: `
4054cc_library {
4055		name: "foo",
4056		sanitize: {
4057				misc_undefined: ["undefined", "nullability"],
4058		},
4059}
4060`,
4061		ExpectedBazelTargets: []string{
4062			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4063				"features": `[
4064        "ubsan_undefined",
4065        "ubsan_nullability",
4066    ]`,
4067				"local_includes": `["."]`,
4068			}),
4069			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4070				"features": `[
4071        "ubsan_undefined",
4072        "ubsan_nullability",
4073    ]`,
4074				"local_includes": `["."]`,
4075			}),
4076		},
4077	})
4078}
4079
4080func TestCcLibraryWithUBSanPropertiesArchSpecific(t *testing.T) {
4081	runCcLibraryTestCase(t, Bp2buildTestCase{
4082		Description:                "cc_library has correct feature select when UBSan props are specified in arch specific blocks",
4083		ModuleTypeUnderTest:        "cc_library",
4084		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4085		Blueprint: `
4086cc_library {
4087		name: "foo",
4088		sanitize: {
4089				misc_undefined: ["undefined", "nullability"],
4090		},
4091		target: {
4092				android: {
4093						sanitize: {
4094								misc_undefined: ["alignment"],
4095						},
4096				},
4097				linux_glibc: {
4098						sanitize: {
4099								integer_overflow: true,
4100						},
4101				},
4102		},
4103}
4104`,
4105		ExpectedBazelTargets: []string{
4106			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4107				"features": `[
4108        "ubsan_undefined",
4109        "ubsan_nullability",
4110    ] + select({
4111        "//build/bazel/platforms/os:android": ["ubsan_alignment"],
4112        "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"],
4113        "//conditions:default": [],
4114    })`,
4115				"local_includes": `["."]`,
4116			}),
4117			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4118				"features": `[
4119        "ubsan_undefined",
4120        "ubsan_nullability",
4121    ] + select({
4122        "//build/bazel/platforms/os:android": ["ubsan_alignment"],
4123        "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"],
4124        "//conditions:default": [],
4125    })`,
4126				"local_includes": `["."]`,
4127			}),
4128		},
4129	})
4130}
4131
4132func TestCcLibraryInApexWithStubSharedLibs(t *testing.T) {
4133	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
4134		Description:                "cc_library with in apex with stub shared_libs and export_shared_lib_headers",
4135		ModuleTypeUnderTest:        "cc_library",
4136		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4137		Blueprint: `
4138cc_library {
4139	name: "barlib",
4140	stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
4141	bazel_module: { bp2build_available: false },
4142}
4143cc_library {
4144	name: "bazlib",
4145	stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
4146	bazel_module: { bp2build_available: false },
4147}
4148cc_library {
4149    name: "foo",
4150	  shared_libs: ["barlib", "bazlib"],
4151    export_shared_lib_headers: ["bazlib"],
4152    apex_available: [
4153        "apex_available:platform",
4154    ],
4155}`,
4156		ExpectedBazelTargets: []string{
4157			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4158				"implementation_dynamic_deps": `select({
4159        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:barlib"],
4160        "//conditions:default": [":barlib"],
4161    })`,
4162				"dynamic_deps": `select({
4163        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:bazlib"],
4164        "//conditions:default": [":bazlib"],
4165    })`,
4166				"local_includes": `["."]`,
4167				"tags":           `["apex_available=apex_available:platform"]`,
4168			}),
4169			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4170				"implementation_dynamic_deps": `select({
4171        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:barlib"],
4172        "//conditions:default": [":barlib"],
4173    })`,
4174				"dynamic_deps": `select({
4175        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:bazlib"],
4176        "//conditions:default": [":bazlib"],
4177    })`,
4178				"local_includes": `["."]`,
4179				"tags":           `["apex_available=apex_available:platform"]`,
4180			}),
4181		},
4182	})
4183}
4184
4185func TestCcLibraryWithThinLto(t *testing.T) {
4186	runCcLibraryTestCase(t, Bp2buildTestCase{
4187		Description:                "cc_library has correct features when thin LTO is enabled",
4188		ModuleTypeUnderTest:        "cc_library",
4189		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4190		Blueprint: `
4191cc_library {
4192	name: "foo",
4193	lto: {
4194		thin: true,
4195	},
4196}`,
4197		ExpectedBazelTargets: []string{
4198			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4199				"features":       `["android_thin_lto"]`,
4200				"local_includes": `["."]`,
4201			}),
4202			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4203				"features":       `["android_thin_lto"]`,
4204				"local_includes": `["."]`,
4205			}),
4206		},
4207	})
4208}
4209
4210func TestCcLibraryWithLtoNever(t *testing.T) {
4211	runCcLibraryTestCase(t, Bp2buildTestCase{
4212		Description:                "cc_library has correct features when LTO is explicitly disabled",
4213		ModuleTypeUnderTest:        "cc_library",
4214		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4215		Blueprint: `
4216cc_library {
4217	name: "foo",
4218	lto: {
4219		never: true,
4220	},
4221}`,
4222		ExpectedBazelTargets: []string{
4223			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4224				"features":       `["-android_thin_lto"]`,
4225				"local_includes": `["."]`,
4226			}),
4227			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4228				"features":       `["-android_thin_lto"]`,
4229				"local_includes": `["."]`,
4230			}),
4231		},
4232	})
4233}
4234
4235func TestCcLibraryWithThinLtoArchSpecific(t *testing.T) {
4236	runCcLibraryTestCase(t, Bp2buildTestCase{
4237		Description:                "cc_library has correct features when LTO differs across arch and os variants",
4238		ModuleTypeUnderTest:        "cc_library",
4239		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4240		Blueprint: `
4241cc_library {
4242	name: "foo",
4243	target: {
4244		android: {
4245			lto: {
4246				thin: true,
4247			},
4248		},
4249	},
4250	arch: {
4251		riscv64: {
4252			lto: {
4253				thin: false,
4254			},
4255		},
4256	},
4257}`,
4258		ExpectedBazelTargets: []string{
4259			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4260				"local_includes": `["."]`,
4261				"features": `select({
4262        "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
4263        "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
4264        "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
4265        "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
4266        "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
4267        "//conditions:default": [],
4268    })`}),
4269			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4270				"local_includes": `["."]`,
4271				"features": `select({
4272        "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
4273        "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
4274        "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
4275        "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
4276        "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
4277        "//conditions:default": [],
4278    })`}),
4279		},
4280	})
4281}
4282
4283func TestCcLibraryWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
4284	runCcLibraryTestCase(t, Bp2buildTestCase{
4285		Description:                "cc_library has correct features when LTO disabled by default but enabled on a particular variant",
4286		ModuleTypeUnderTest:        "cc_library",
4287		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4288		Blueprint: `
4289cc_library {
4290	name: "foo",
4291	lto: {
4292		never: true,
4293	},
4294	target: {
4295		android: {
4296			lto: {
4297				thin: true,
4298				never: false,
4299			},
4300		},
4301	},
4302}`,
4303		ExpectedBazelTargets: []string{
4304			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4305				"local_includes": `["."]`,
4306				"features": `select({
4307        "//build/bazel/platforms/os:android": ["android_thin_lto"],
4308        "//conditions:default": ["-android_thin_lto"],
4309    })`,
4310			}),
4311			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4312				"local_includes": `["."]`,
4313				"features": `select({
4314        "//build/bazel/platforms/os:android": ["android_thin_lto"],
4315        "//conditions:default": ["-android_thin_lto"],
4316    })`,
4317			}),
4318		},
4319	})
4320}
4321
4322func TestCcLibraryWithThinLtoWholeProgramVtables(t *testing.T) {
4323	runCcLibraryTestCase(t, Bp2buildTestCase{
4324		Description:                "cc_library has correct features when thin LTO is enabled with whole_program_vtables",
4325		ModuleTypeUnderTest:        "cc_library",
4326		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4327		Blueprint: `
4328cc_library {
4329	name: "foo",
4330	lto: {
4331		thin: true,
4332	},
4333	whole_program_vtables: true,
4334}`,
4335		ExpectedBazelTargets: []string{
4336			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
4337				"features": `[
4338        "android_thin_lto",
4339        "android_thin_lto_whole_program_vtables",
4340    ]`,
4341				"local_includes": `["."]`,
4342			}),
4343			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
4344				"features": `[
4345        "android_thin_lto",
4346        "android_thin_lto_whole_program_vtables",
4347    ]`,
4348				"local_includes": `["."]`,
4349			}),
4350		},
4351	})
4352}
4353
4354func TestCcLibraryCppFlagsInProductVariables(t *testing.T) {
4355	runCcLibraryTestCase(t, Bp2buildTestCase{
4356		Description:                "cc_library cppflags in product variables",
4357		ModuleTypeUnderTest:        "cc_library",
4358		ModuleTypeUnderTestFactory: cc.LibraryFactory,
4359		Blueprint: soongCcLibraryPreamble + `cc_library {
4360    name: "a",
4361    srcs: ["a.cpp"],
4362    cppflags: [
4363        "-Wextra",
4364        "-DDEBUG_ONLY_CODE=0",
4365    ],
4366    product_variables: {
4367        eng: {
4368            cppflags: [
4369                "-UDEBUG_ONLY_CODE",
4370                "-DDEBUG_ONLY_CODE=1",
4371            ],
4372        },
4373    },
4374    include_build_directory: false,
4375}
4376`,
4377		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
4378			"cppflags": `[
4379        "-Wextra",
4380        "-DDEBUG_ONLY_CODE=0",
4381    ] + select({
4382        "//build/bazel/product_variables:eng": [
4383            "-UDEBUG_ONLY_CODE",
4384            "-DDEBUG_ONLY_CODE=1",
4385        ],
4386        "//conditions:default": [],
4387    })`,
4388			"srcs": `["a.cpp"]`,
4389		}),
4390	},
4391	)
4392}
4393