• 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	"testing"
19
20	"android/soong/android"
21	"android/soong/cc"
22)
23
24const (
25	// See cc/testing.go for more context
26	// TODO(alexmarquez): Split out the preamble into common code?
27	soongCcLibrarySharedPreamble = soongCcLibraryStaticPreamble
28)
29
30func registerCcLibrarySharedModuleTypes(ctx android.RegistrationContext) {
31	cc.RegisterCCBuildComponents(ctx)
32	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
33	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
34	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
35}
36
37func runCcLibrarySharedTestCase(t *testing.T, tc Bp2buildTestCase) {
38	t.Helper()
39	t.Parallel()
40	(&tc).ModuleTypeUnderTest = "cc_library_shared"
41	(&tc).ModuleTypeUnderTestFactory = cc.LibrarySharedFactory
42	RunBp2BuildTestCase(t, registerCcLibrarySharedModuleTypes, tc)
43}
44
45func TestCcLibrarySharedSimple(t *testing.T) {
46	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
47		Description: "cc_library_shared simple overall test",
48		Filesystem: map[string]string{
49			// NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
50			"include_dir_1/include_dir_1_a.h": "",
51			"include_dir_1/include_dir_1_b.h": "",
52			"include_dir_2/include_dir_2_a.h": "",
53			"include_dir_2/include_dir_2_b.h": "",
54			// NOTE: local_include_dir headers *should not* appear in Bazel hdrs later (?)
55			"local_include_dir_1/local_include_dir_1_a.h": "",
56			"local_include_dir_1/local_include_dir_1_b.h": "",
57			"local_include_dir_2/local_include_dir_2_a.h": "",
58			"local_include_dir_2/local_include_dir_2_b.h": "",
59			// NOTE: export_include_dir headers *should* appear in Bazel hdrs later
60			"export_include_dir_1/export_include_dir_1_a.h": "",
61			"export_include_dir_1/export_include_dir_1_b.h": "",
62			"export_include_dir_2/export_include_dir_2_a.h": "",
63			"export_include_dir_2/export_include_dir_2_b.h": "",
64			// NOTE: Soong implicitly includes headers in the current directory
65			"implicit_include_1.h": "",
66			"implicit_include_2.h": "",
67		},
68		Blueprint: soongCcLibrarySharedPreamble + `
69cc_library_headers {
70    name: "header_lib_1",
71    export_include_dirs: ["header_lib_1"],
72    bazel_module: { bp2build_available: false },
73}
74
75cc_library_headers {
76    name: "header_lib_2",
77    export_include_dirs: ["header_lib_2"],
78    bazel_module: { bp2build_available: false },
79}
80
81cc_library_shared {
82    name: "shared_lib_1",
83    srcs: ["shared_lib_1.cc"],
84    bazel_module: { bp2build_available: false },
85}
86
87cc_library_shared {
88    name: "shared_lib_2",
89    srcs: ["shared_lib_2.cc"],
90    bazel_module: { bp2build_available: false },
91}
92
93cc_library_static {
94    name: "whole_static_lib_1",
95    srcs: ["whole_static_lib_1.cc"],
96    bazel_module: { bp2build_available: false },
97}
98
99cc_library_static {
100    name: "whole_static_lib_2",
101    srcs: ["whole_static_lib_2.cc"],
102    bazel_module: { bp2build_available: false },
103}
104
105cc_library_shared {
106    name: "foo_shared",
107    srcs: [
108        "foo_shared1.cc",
109        "foo_shared2.cc",
110    ],
111    cflags: [
112        "-Dflag1",
113        "-Dflag2"
114    ],
115    shared_libs: [
116        "shared_lib_1",
117        "shared_lib_2"
118    ],
119    whole_static_libs: [
120        "whole_static_lib_1",
121        "whole_static_lib_2"
122    ],
123    include_dirs: [
124        "include_dir_1",
125        "include_dir_2",
126    ],
127    local_include_dirs: [
128        "local_include_dir_1",
129        "local_include_dir_2",
130    ],
131    export_include_dirs: [
132        "export_include_dir_1",
133        "export_include_dir_2"
134    ],
135    header_libs: [
136        "header_lib_1",
137        "header_lib_2"
138    ],
139    sdk_version: "current",
140    min_sdk_version: "29",
141
142    // TODO: Also support export_header_lib_headers
143}`,
144		ExpectedBazelTargets: []string{
145			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
146				"absolute_includes": `[
147        "include_dir_1",
148        "include_dir_2",
149    ]`,
150				"copts": `[
151        "-Dflag1",
152        "-Dflag2",
153    ]`,
154				"export_includes": `[
155        "export_include_dir_1",
156        "export_include_dir_2",
157    ]`,
158				"implementation_deps": `[
159        ":header_lib_1",
160        ":header_lib_2",
161    ]`,
162				"implementation_dynamic_deps": `[
163        ":shared_lib_1",
164        ":shared_lib_2",
165    ]`,
166				"local_includes": `[
167        "local_include_dir_1",
168        "local_include_dir_2",
169        ".",
170    ]`,
171				"srcs": `[
172        "foo_shared1.cc",
173        "foo_shared2.cc",
174    ]`,
175				"whole_archive_deps": `[
176        ":whole_static_lib_1",
177        ":whole_static_lib_2",
178    ]`,
179				"sdk_version":     `"current"`,
180				"min_sdk_version": `"29"`,
181			}),
182		},
183	})
184}
185
186func TestCcLibrarySharedArchSpecificSharedLib(t *testing.T) {
187	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
188		Description: "cc_library_shared arch-specific shared_libs with whole_static_libs",
189		Filesystem:  map[string]string{},
190		Blueprint: soongCcLibrarySharedPreamble + `
191cc_library_static {
192    name: "static_dep",
193    bazel_module: { bp2build_available: false },
194}
195cc_library_shared {
196    name: "shared_dep",
197    bazel_module: { bp2build_available: false },
198}
199cc_library_shared {
200    name: "foo_shared",
201    arch: { arm64: { shared_libs: ["shared_dep"], whole_static_libs: ["static_dep"] } },
202    include_build_directory: false,
203}`,
204		ExpectedBazelTargets: []string{
205			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
206				"implementation_dynamic_deps": `select({
207        "//build/bazel/platforms/arch:arm64": [":shared_dep"],
208        "//conditions:default": [],
209    })`,
210				"whole_archive_deps": `select({
211        "//build/bazel/platforms/arch:arm64": [":static_dep"],
212        "//conditions:default": [],
213    })`,
214			}),
215		},
216	})
217}
218
219func TestCcLibrarySharedOsSpecificSharedLib(t *testing.T) {
220	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
221		Description: "cc_library_shared os-specific shared_libs",
222		Filesystem:  map[string]string{},
223		Blueprint: soongCcLibrarySharedPreamble + `
224cc_library_shared {
225    name: "shared_dep",
226    bazel_module: { bp2build_available: false },
227}
228cc_library_shared {
229    name: "foo_shared",
230    target: { android: { shared_libs: ["shared_dep"], } },
231    include_build_directory: false,
232}`,
233		ExpectedBazelTargets: []string{
234			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
235				"implementation_dynamic_deps": `select({
236        "//build/bazel/platforms/os:android": [":shared_dep"],
237        "//conditions:default": [],
238    })`,
239			}),
240		},
241	})
242}
243
244func TestCcLibrarySharedBaseArchOsSpecificSharedLib(t *testing.T) {
245	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
246		Description: "cc_library_shared base, arch, and os-specific shared_libs",
247		Filesystem:  map[string]string{},
248		Blueprint: soongCcLibrarySharedPreamble + `
249cc_library_shared {
250    name: "shared_dep",
251    bazel_module: { bp2build_available: false },
252}
253cc_library_shared {
254    name: "shared_dep2",
255    bazel_module: { bp2build_available: false },
256}
257cc_library_shared {
258    name: "shared_dep3",
259    bazel_module: { bp2build_available: false },
260}
261cc_library_shared {
262    name: "foo_shared",
263    shared_libs: ["shared_dep"],
264    target: { android: { shared_libs: ["shared_dep2"] } },
265    arch: { arm64: { shared_libs: ["shared_dep3"] } },
266    include_build_directory: false,
267}`,
268		ExpectedBazelTargets: []string{
269			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
270				"implementation_dynamic_deps": `[":shared_dep"] + select({
271        "//build/bazel/platforms/arch:arm64": [":shared_dep3"],
272        "//conditions:default": [],
273    }) + select({
274        "//build/bazel/platforms/os:android": [":shared_dep2"],
275        "//conditions:default": [],
276    })`,
277			}),
278		},
279	})
280}
281
282func TestCcLibrarySharedSimpleExcludeSrcs(t *testing.T) {
283	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
284		Description: "cc_library_shared simple exclude_srcs",
285		Filesystem: map[string]string{
286			"common.c":       "",
287			"foo-a.c":        "",
288			"foo-excluded.c": "",
289		},
290		Blueprint: soongCcLibrarySharedPreamble + `
291cc_library_shared {
292    name: "foo_shared",
293    srcs: ["common.c", "foo-*.c"],
294    exclude_srcs: ["foo-excluded.c"],
295    include_build_directory: false,
296}`,
297		ExpectedBazelTargets: []string{
298			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
299				"srcs_c": `[
300        "common.c",
301        "foo-a.c",
302    ]`,
303			}),
304		},
305	})
306}
307
308func TestCcLibrarySharedStrip(t *testing.T) {
309	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
310		Description: "cc_library_shared stripping",
311		Filesystem:  map[string]string{},
312		Blueprint: soongCcLibrarySharedPreamble + `
313cc_library_shared {
314    name: "foo_shared",
315    strip: {
316        keep_symbols: false,
317        keep_symbols_and_debug_frame: true,
318        keep_symbols_list: ["sym", "sym2"],
319        all: true,
320        none: false,
321    },
322    include_build_directory: false,
323}`,
324		ExpectedBazelTargets: []string{
325			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
326				"strip": `{
327        "all": True,
328        "keep_symbols": False,
329        "keep_symbols_and_debug_frame": True,
330        "keep_symbols_list": [
331            "sym",
332            "sym2",
333        ],
334        "none": False,
335    }`,
336			}),
337		},
338	})
339}
340
341func TestCcLibrarySharedVersionScriptAndDynamicList(t *testing.T) {
342	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
343		Description: "cc_library_shared version script and dynamic list",
344		Filesystem: map[string]string{
345			"version_script": "",
346			"dynamic.list":   "",
347		},
348		Blueprint: soongCcLibrarySharedPreamble + `
349cc_library_shared {
350    name: "foo_shared",
351    version_script: "version_script",
352    dynamic_list: "dynamic.list",
353    include_build_directory: false,
354}`,
355		ExpectedBazelTargets: []string{
356			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
357				"additional_linker_inputs": `[
358        "version_script",
359        "dynamic.list",
360    ]`,
361				"linkopts": `[
362        "-Wl,--version-script,$(location version_script)",
363        "-Wl,--dynamic-list,$(location dynamic.list)",
364    ]`,
365			}),
366		},
367	})
368}
369
370func TestCcLibraryLdflagsSplitBySpaceSoongAdded(t *testing.T) {
371	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
372		Description: "ldflags are split by spaces except for the ones added by soong (version script and dynamic list)",
373		Filesystem: map[string]string{
374			"version_script": "",
375			"dynamic.list":   "",
376		},
377		Blueprint: `
378cc_library_shared {
379    name: "foo",
380    ldflags: [
381        "--nospace_flag",
382        "-z spaceflag",
383    ],
384    version_script: "version_script",
385    dynamic_list: "dynamic.list",
386    include_build_directory: false,
387}`,
388		ExpectedBazelTargets: []string{
389			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
390				"additional_linker_inputs": `[
391        "version_script",
392        "dynamic.list",
393    ]`,
394				"linkopts": `[
395        "--nospace_flag",
396        "-z",
397        "spaceflag",
398        "-Wl,--version-script,$(location version_script)",
399        "-Wl,--dynamic-list,$(location dynamic.list)",
400    ]`,
401			}),
402		},
403	})
404}
405
406func TestCcLibrarySharedNoCrtTrue(t *testing.T) {
407	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
408		Description: "cc_library_shared - nocrt: true disables feature",
409		Filesystem: map[string]string{
410			"impl.cpp": "",
411		},
412		Blueprint: soongCcLibraryPreamble + `
413cc_library_shared {
414    name: "foo_shared",
415    srcs: ["impl.cpp"],
416    nocrt: true,
417    include_build_directory: false,
418}
419`,
420		ExpectedBazelTargets: []string{
421			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
422				"features": `["-link_crt"]`,
423				"srcs":     `["impl.cpp"]`,
424			}),
425		},
426	})
427}
428
429func TestCcLibrarySharedNoCrtFalse(t *testing.T) {
430	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
431		Description: "cc_library_shared - nocrt: false doesn't disable feature",
432		Filesystem: map[string]string{
433			"impl.cpp": "",
434		},
435		Blueprint: soongCcLibraryPreamble + `
436cc_library_shared {
437    name: "foo_shared",
438    srcs: ["impl.cpp"],
439    nocrt: false,
440    include_build_directory: false,
441}
442`,
443		ExpectedBazelTargets: []string{
444			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
445				"srcs": `["impl.cpp"]`,
446			}),
447		},
448	})
449}
450
451func TestCcLibrarySharedNoCrtArchVariant(t *testing.T) {
452	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
453		Description: "cc_library_shared - nocrt in select",
454		Filesystem: map[string]string{
455			"impl.cpp": "",
456		},
457		Blueprint: soongCcLibraryPreamble + `
458cc_library_shared {
459    name: "foo_shared",
460    srcs: ["impl.cpp"],
461    arch: {
462        arm: {
463            nocrt: true,
464        },
465        x86: {
466            nocrt: false,
467        },
468    },
469    include_build_directory: false,
470}
471`,
472		ExpectedBazelTargets: []string{
473			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
474				"features": `select({
475        "//build/bazel/platforms/arch:arm": ["-link_crt"],
476        "//conditions:default": [],
477    })`,
478				"srcs": `["impl.cpp"]`,
479			}),
480		},
481	})
482}
483
484func TestCcLibrarySharedProto(t *testing.T) {
485	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
486		Blueprint: soongCcProtoPreamble + `cc_library_shared {
487	name: "foo",
488	srcs: ["foo.proto"],
489	proto: {
490		export_proto_headers: true,
491	},
492	include_build_directory: false,
493}`,
494		ExpectedBazelTargets: []string{
495			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
496				"srcs": `["foo.proto"]`,
497			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
498				"deps": `[":foo_proto"]`,
499			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
500				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
501				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
502			}),
503		},
504	})
505}
506
507func TestCcLibrarySharedUseVersionLib(t *testing.T) {
508	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
509		Filesystem: map[string]string{
510			soongCcVersionLibBpPath: soongCcVersionLibBp,
511		},
512		Blueprint: soongCcProtoPreamble + `cc_library_shared {
513        name: "foo",
514        use_version_lib: true,
515        include_build_directory: false,
516}`,
517		ExpectedBazelTargets: []string{
518			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
519				"use_version_lib":                   "True",
520				"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
521			}),
522		},
523	})
524}
525
526func TestCcLibrarySharedStubs(t *testing.T) {
527	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
528		Description:                "cc_library_shared stubs",
529		ModuleTypeUnderTest:        "cc_library_shared",
530		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
531		Dir:                        "foo/bar",
532		Filesystem: map[string]string{
533			"foo/bar/Android.bp": `
534cc_library_shared {
535	name: "a",
536	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
537	bazel_module: { bp2build_available: true },
538	include_build_directory: false,
539}
540`,
541		},
542		Blueprint: soongCcLibraryPreamble,
543		ExpectedBazelTargets: []string{makeCcStubSuiteTargets("a", AttrNameToString{
544			"soname":               `"a.so"`,
545			"source_library_label": `"//foo/bar:a"`,
546			"stubs_symbol_file":    `"a.map.txt"`,
547			"stubs_versions": `[
548        "28",
549        "29",
550        "current",
551    ]`,
552		}),
553			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
554				"stubs_symbol_file": `"a.map.txt"`,
555			}),
556		},
557	})
558}
559
560func TestCcLibrarySharedStubs_UseImplementationInSameApex(t *testing.T) {
561	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
562		Description:                "cc_library_shared stubs",
563		ModuleTypeUnderTest:        "cc_library_shared",
564		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
565		Blueprint: soongCcLibrarySharedPreamble + `
566cc_library_shared {
567	name: "a",
568	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
569	bazel_module: { bp2build_available: false },
570	include_build_directory: false,
571	apex_available: ["made_up_apex"],
572}
573cc_library_shared {
574	name: "b",
575	shared_libs: [":a"],
576	include_build_directory: false,
577	apex_available: ["made_up_apex"],
578}
579`,
580		ExpectedBazelTargets: []string{
581			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
582				"implementation_dynamic_deps": `[":a"]`,
583				"tags":                        `["apex_available=made_up_apex"]`,
584			}),
585		},
586	})
587}
588
589func TestCcLibrarySharedStubs_UseStubsInDifferentApex(t *testing.T) {
590	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
591		Description:                "cc_library_shared stubs",
592		ModuleTypeUnderTest:        "cc_library_shared",
593		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
594		Blueprint: soongCcLibrarySharedPreamble + `
595cc_library_shared {
596	name: "a",
597	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
598	bazel_module: { bp2build_available: false },
599	include_build_directory: false,
600	apex_available: ["apex_a"],
601}
602cc_library_shared {
603	name: "b",
604	shared_libs: [":a"],
605	include_build_directory: false,
606	apex_available: ["apex_b"],
607}
608`,
609		ExpectedBazelTargets: []string{
610			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
611				"implementation_dynamic_deps": `select({
612        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
613        "//conditions:default": [":a"],
614    })`,
615				"tags": `["apex_available=apex_b"]`,
616			}),
617		},
618	})
619}
620
621func TestCcLibrarySharedStubs_IgnorePlatformAvailable(t *testing.T) {
622	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
623		Description:                "cc_library_shared stubs",
624		ModuleTypeUnderTest:        "cc_library_shared",
625		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
626		Blueprint: soongCcLibrarySharedPreamble + `
627cc_library_shared {
628	name: "a",
629	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
630	bazel_module: { bp2build_available: false },
631	include_build_directory: false,
632	apex_available: ["//apex_available:platform", "apex_a"],
633}
634cc_library_shared {
635	name: "b",
636	shared_libs: [":a"],
637	include_build_directory: false,
638	apex_available: ["//apex_available:platform", "apex_b"],
639}
640`,
641		ExpectedBazelTargets: []string{
642			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
643				"implementation_dynamic_deps": `select({
644        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
645        "//conditions:default": [":a"],
646    })`,
647				"tags": `[
648        "apex_available=//apex_available:platform",
649        "apex_available=apex_b",
650    ]`,
651			}),
652		},
653	})
654}
655
656func TestCcLibrarySharedStubs_MultipleApexAvailable(t *testing.T) {
657	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
658		ModuleTypeUnderTest:        "cc_library_shared",
659		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
660		Blueprint: soongCcLibrarySharedPreamble + `
661cc_library_shared {
662	name: "a",
663	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
664	bazel_module: { bp2build_available: false },
665	include_build_directory: false,
666	apex_available: ["//apex_available:platform", "apex_a", "apex_b"],
667}
668cc_library_shared {
669	name: "b",
670	shared_libs: [":a"],
671	include_build_directory: false,
672	apex_available: ["//apex_available:platform", "apex_b"],
673}
674
675cc_library_shared {
676	name: "c",
677	shared_libs: [":a"],
678	include_build_directory: false,
679	apex_available: ["//apex_available:platform", "apex_a", "apex_b"],
680}
681`,
682		ExpectedBazelTargets: []string{
683			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
684				"implementation_dynamic_deps": `select({
685        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
686        "//conditions:default": [":a"],
687    })`,
688				"tags": `[
689        "apex_available=//apex_available:platform",
690        "apex_available=apex_b",
691    ]`,
692			}),
693			MakeBazelTarget("cc_library_shared", "c", AttrNameToString{
694				"implementation_dynamic_deps": `[":a"]`,
695				"tags": `[
696        "apex_available=//apex_available:platform",
697        "apex_available=apex_a",
698        "apex_available=apex_b",
699    ]`,
700			}),
701		},
702	})
703}
704
705func TestCcLibrarySharedSystemSharedLibsSharedEmpty(t *testing.T) {
706	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
707		Description:                "cc_library_shared system_shared_libs empty shared default",
708		ModuleTypeUnderTest:        "cc_library_shared",
709		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
710		Blueprint: soongCcLibrarySharedPreamble + `
711cc_defaults {
712    name: "empty_defaults",
713    shared: {
714        system_shared_libs: [],
715    },
716    include_build_directory: false,
717}
718cc_library_shared {
719    name: "empty",
720    defaults: ["empty_defaults"],
721}
722`,
723		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_shared", "empty", AttrNameToString{
724			"system_dynamic_deps": "[]",
725		})},
726	})
727}
728
729func TestCcLibrarySharedConvertLex(t *testing.T) {
730	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
731		Description:                "cc_library_shared with lex files",
732		ModuleTypeUnderTest:        "cc_library_shared",
733		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
734		Filesystem: map[string]string{
735			"foo.c":   "",
736			"bar.cc":  "",
737			"foo1.l":  "",
738			"bar1.ll": "",
739			"foo2.l":  "",
740			"bar2.ll": "",
741		},
742		Blueprint: `cc_library_shared {
743	name: "foo_lib",
744	srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"],
745	lex: { flags: ["--foo_flags"] },
746	include_build_directory: false,
747	bazel_module: { bp2build_available: true },
748}`,
749		ExpectedBazelTargets: []string{
750			MakeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
751				"srcs": `[
752        "foo1.l",
753        "foo2.l",
754    ]`,
755				"lexopts": `["--foo_flags"]`,
756			}),
757			MakeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
758				"srcs": `[
759        "bar1.ll",
760        "bar2.ll",
761    ]`,
762				"lexopts": `["--foo_flags"]`,
763			}),
764			MakeBazelTarget("cc_library_shared", "foo_lib", AttrNameToString{
765				"srcs": `[
766        "bar.cc",
767        ":foo_lib_genlex_ll",
768    ]`,
769				"srcs_c": `[
770        "foo.c",
771        ":foo_lib_genlex_l",
772    ]`,
773			}),
774		},
775	})
776}
777
778func TestCcLibrarySharedClangUnknownFlags(t *testing.T) {
779	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
780		Blueprint: soongCcProtoPreamble + `cc_library_shared {
781	name: "foo",
782	conlyflags: ["-a", "-finline-functions"],
783	cflags: ["-b","-finline-functions"],
784	cppflags: ["-c", "-finline-functions"],
785	ldflags: ["-d","-finline-functions", "-e"],
786	include_build_directory: false,
787}`,
788		ExpectedBazelTargets: []string{
789			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
790				"conlyflags": `["-a"]`,
791				"copts":      `["-b"]`,
792				"cppflags":   `["-c"]`,
793				"linkopts": `[
794        "-d",
795        "-e",
796    ]`,
797			}),
798		},
799	})
800}
801
802func TestCCLibraryFlagSpaceSplitting(t *testing.T) {
803	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
804		Blueprint: soongCcProtoPreamble + `cc_library_shared {
805	name: "foo",
806	conlyflags: [ "-include header.h"],
807	cflags: ["-include header.h"],
808	cppflags: ["-include header.h"],
809	version_script: "version_script",
810	include_build_directory: false,
811}`,
812		ExpectedBazelTargets: []string{
813			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
814				"additional_linker_inputs": `["version_script"]`,
815				"conlyflags": `[
816        "-include",
817        "header.h",
818    ]`,
819				"copts": `[
820        "-include",
821        "header.h",
822    ]`,
823				"cppflags": `[
824        "-include",
825        "header.h",
826    ]`,
827				"linkopts": `["-Wl,--version-script,$(location version_script)"]`,
828			}),
829		},
830	})
831}
832
833func TestCCLibrarySharedRuntimeDeps(t *testing.T) {
834	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
835		Blueprint: `cc_library_shared {
836	name: "bar",
837}
838
839cc_library_shared {
840  name: "foo",
841  runtime_libs: ["foo"],
842}`,
843		ExpectedBazelTargets: []string{
844			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
845				"local_includes": `["."]`,
846			}),
847			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
848				"runtime_deps":   `[":foo"]`,
849				"local_includes": `["."]`,
850			}),
851		},
852	})
853}
854
855func TestCcLibrarySharedEmptySuffix(t *testing.T) {
856	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
857		Description: "cc_library_shared with empty suffix",
858		Filesystem: map[string]string{
859			"foo.c": "",
860		},
861		Blueprint: soongCcLibrarySharedPreamble + `
862cc_library_shared {
863    name: "foo_shared",
864    suffix: "",
865    srcs: ["foo.c"],
866    include_build_directory: false,
867}`,
868		ExpectedBazelTargets: []string{
869			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
870				"srcs_c": `["foo.c"]`,
871				"suffix": `""`,
872			}),
873		},
874	})
875}
876
877func TestCcLibrarySharedSuffix(t *testing.T) {
878	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
879		Description: "cc_library_shared with suffix",
880		Filesystem: map[string]string{
881			"foo.c": "",
882		},
883		Blueprint: soongCcLibrarySharedPreamble + `
884cc_library_shared {
885    name: "foo_shared",
886    suffix: "-suf",
887    srcs: ["foo.c"],
888    include_build_directory: false,
889}`,
890		ExpectedBazelTargets: []string{
891			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
892				"srcs_c": `["foo.c"]`,
893				"suffix": `"-suf"`,
894			}),
895		},
896	})
897}
898
899func TestCcLibrarySharedArchVariantSuffix(t *testing.T) {
900	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
901		Description: "cc_library_shared with arch-variant suffix",
902		Filesystem: map[string]string{
903			"foo.c": "",
904		},
905		Blueprint: soongCcLibrarySharedPreamble + `
906cc_library_shared {
907    name: "foo_shared",
908    arch: {
909        arm64: { suffix: "-64" },
910        arm:   { suffix: "-32" },
911		},
912    srcs: ["foo.c"],
913    include_build_directory: false,
914}`,
915		ExpectedBazelTargets: []string{
916			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
917				"srcs_c": `["foo.c"]`,
918				"suffix": `select({
919        "//build/bazel/platforms/arch:arm": "-32",
920        "//build/bazel/platforms/arch:arm64": "-64",
921        "//conditions:default": None,
922    })`,
923			}),
924		},
925	})
926}
927
928func TestCcLibrarySharedWithSyspropSrcs(t *testing.T) {
929	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
930		Description: "cc_library_shared with sysprop sources",
931		Blueprint: `
932cc_library_shared {
933	name: "foo",
934	srcs: [
935		"bar.sysprop",
936		"baz.sysprop",
937		"blah.cpp",
938	],
939	min_sdk_version: "5",
940}`,
941		ExpectedBazelTargets: []string{
942			MakeBazelTarget("sysprop_library", "foo_sysprop_library", AttrNameToString{
943				"srcs": `[
944        "bar.sysprop",
945        "baz.sysprop",
946    ]`,
947			}),
948			MakeBazelTarget("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
949				"dep":             `":foo_sysprop_library"`,
950				"min_sdk_version": `"5"`,
951			}),
952			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
953				"srcs":               `["blah.cpp"]`,
954				"local_includes":     `["."]`,
955				"min_sdk_version":    `"5"`,
956				"whole_archive_deps": `[":foo_cc_sysprop_library_static"]`,
957			}),
958		},
959	})
960}
961
962func TestCcLibrarySharedWithSyspropSrcsSomeConfigs(t *testing.T) {
963	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
964		Description: "cc_library_shared with sysprop sources in some configs but not others",
965		Blueprint: `
966cc_library_shared {
967	name: "foo",
968	srcs: [
969		"blah.cpp",
970	],
971	target: {
972		android: {
973			srcs: ["bar.sysprop"],
974		},
975	},
976	min_sdk_version: "5",
977}`,
978		ExpectedBazelTargets: []string{
979			MakeBazelTarget("sysprop_library", "foo_sysprop_library", AttrNameToString{
980				"srcs": `select({
981        "//build/bazel/platforms/os:android": ["bar.sysprop"],
982        "//conditions:default": [],
983    })`,
984			}),
985			MakeBazelTarget("cc_sysprop_library_static", "foo_cc_sysprop_library_static", AttrNameToString{
986				"dep":             `":foo_sysprop_library"`,
987				"min_sdk_version": `"5"`,
988			}),
989			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
990				"srcs":            `["blah.cpp"]`,
991				"local_includes":  `["."]`,
992				"min_sdk_version": `"5"`,
993				"whole_archive_deps": `select({
994        "//build/bazel/platforms/os:android": [":foo_cc_sysprop_library_static"],
995        "//conditions:default": [],
996    })`,
997			}),
998		},
999	})
1000}
1001
1002func TestCcLibrarySharedHeaderAbiChecker(t *testing.T) {
1003	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1004		Description: "cc_library_shared with header abi checker",
1005		Blueprint: `cc_library_shared {
1006    name: "foo",
1007    header_abi_checker: {
1008        enabled: true,
1009        symbol_file: "a.map.txt",
1010        exclude_symbol_versions: [
1011						"29",
1012						"30",
1013				],
1014        exclude_symbol_tags: [
1015						"tag1",
1016						"tag2",
1017				],
1018        check_all_apis: true,
1019        diff_flags: ["-allow-adding-removing-weak-symbols"],
1020    },
1021    include_build_directory: false,
1022}`,
1023		ExpectedBazelTargets: []string{
1024			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1025				"abi_checker_enabled":     `True`,
1026				"abi_checker_symbol_file": `"a.map.txt"`,
1027				"abi_checker_exclude_symbol_versions": `[
1028        "29",
1029        "30",
1030    ]`,
1031				"abi_checker_exclude_symbol_tags": `[
1032        "tag1",
1033        "tag2",
1034    ]`,
1035				"abi_checker_check_all_apis": `True`,
1036				"abi_checker_diff_flags":     `["-allow-adding-removing-weak-symbols"]`,
1037			}),
1038		},
1039	})
1040}
1041
1042func TestCcLibrarySharedWithIntegerOverflowProperty(t *testing.T) {
1043	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1044		Description: "cc_library_shared has correct features when integer_overflow property is provided",
1045		Blueprint: `
1046cc_library_shared {
1047		name: "foo",
1048		sanitize: {
1049				integer_overflow: true,
1050		},
1051}
1052`,
1053		ExpectedBazelTargets: []string{
1054			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1055				"features":       `["ubsan_integer_overflow"]`,
1056				"local_includes": `["."]`,
1057			}),
1058		},
1059	})
1060}
1061
1062func TestCcLibrarySharedWithMiscUndefinedProperty(t *testing.T) {
1063	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1064		Description: "cc_library_shared has correct features when misc_undefined property is provided",
1065		Blueprint: `
1066cc_library_shared {
1067		name: "foo",
1068		sanitize: {
1069				misc_undefined: ["undefined", "nullability"],
1070		},
1071}
1072`,
1073		ExpectedBazelTargets: []string{
1074			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1075				"features": `[
1076        "ubsan_undefined",
1077        "ubsan_nullability",
1078    ]`,
1079				"local_includes": `["."]`,
1080			}),
1081		},
1082	})
1083}
1084
1085func TestCcLibrarySharedWithUBSanPropertiesArchSpecific(t *testing.T) {
1086	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1087		Description: "cc_library_shared has correct feature select when UBSan props are specified in arch specific blocks",
1088		Blueprint: `
1089cc_library_shared {
1090		name: "foo",
1091		sanitize: {
1092				misc_undefined: ["undefined", "nullability"],
1093		},
1094		target: {
1095				android: {
1096						sanitize: {
1097								misc_undefined: ["alignment"],
1098						},
1099				},
1100				linux_glibc: {
1101						sanitize: {
1102								integer_overflow: true,
1103						},
1104				},
1105		},
1106}
1107`,
1108		ExpectedBazelTargets: []string{
1109			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1110				"features": `[
1111        "ubsan_undefined",
1112        "ubsan_nullability",
1113    ] + select({
1114        "//build/bazel/platforms/os:android": ["ubsan_alignment"],
1115        "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"],
1116        "//conditions:default": [],
1117    })`,
1118				"local_includes": `["."]`,
1119			}),
1120		},
1121	})
1122}
1123
1124func TestCcLibrarySharedWithThinLto(t *testing.T) {
1125	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1126		Description: "cc_library_shared has correct features when thin lto is enabled",
1127		Blueprint: `
1128cc_library_shared {
1129	name: "foo",
1130	lto: {
1131		thin: true,
1132	},
1133}
1134`,
1135		ExpectedBazelTargets: []string{
1136			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1137				"features":       `["android_thin_lto"]`,
1138				"local_includes": `["."]`,
1139			}),
1140		},
1141	})
1142}
1143
1144func TestCcLibrarySharedWithLtoNever(t *testing.T) {
1145	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1146		Description: "cc_library_shared has correct features when thin lto is enabled",
1147		Blueprint: `
1148cc_library_shared {
1149	name: "foo",
1150	lto: {
1151		never: true,
1152	},
1153}
1154`,
1155		ExpectedBazelTargets: []string{
1156			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1157				"features":       `["-android_thin_lto"]`,
1158				"local_includes": `["."]`,
1159			}),
1160		},
1161	})
1162}
1163
1164func TestCcLibrarySharedWithThinLtoArchSpecific(t *testing.T) {
1165	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1166		Description: "cc_library_shared has correct features when LTO differs across arch and os variants",
1167		Blueprint: `
1168cc_library_shared {
1169	name: "foo",
1170	target: {
1171		android: {
1172			lto: {
1173				thin: true,
1174			},
1175		},
1176	},
1177	arch: {
1178		riscv64: {
1179			lto: {
1180				thin: false,
1181			},
1182		},
1183	},
1184}`,
1185		ExpectedBazelTargets: []string{
1186			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1187				"local_includes": `["."]`,
1188				"features": `select({
1189        "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
1190        "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
1191        "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
1192        "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
1193        "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
1194        "//conditions:default": [],
1195    })`}),
1196		},
1197	})
1198}
1199
1200func TestCcLibrarySharedWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
1201	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1202		Description: "cc_library_shared with thin lto disabled by default but enabled on a particular variant",
1203		Blueprint: `
1204cc_library_shared {
1205	name: "foo",
1206	lto: {
1207		never: true,
1208	},
1209	target: {
1210		android: {
1211			lto: {
1212				thin: true,
1213				never: false,
1214			},
1215		},
1216	},
1217}`,
1218		ExpectedBazelTargets: []string{
1219			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1220				"local_includes": `["."]`,
1221				"features": `select({
1222        "//build/bazel/platforms/os:android": ["android_thin_lto"],
1223        "//conditions:default": ["-android_thin_lto"],
1224    })`,
1225			}),
1226		},
1227	})
1228}
1229
1230func TestCcLibrarySharedWithThinLtoAndWholeProgramVtables(t *testing.T) {
1231	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1232		Description: "cc_library_shared has correct features when thin LTO is enabled with whole_program_vtables",
1233		Blueprint: `
1234cc_library_shared {
1235	name: "foo",
1236	lto: {
1237		thin: true,
1238	},
1239	whole_program_vtables: true,
1240}
1241`,
1242		ExpectedBazelTargets: []string{
1243			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
1244				"features": `[
1245        "android_thin_lto",
1246        "android_thin_lto_whole_program_vtables",
1247    ]`,
1248				"local_includes": `["."]`,
1249			}),
1250		},
1251	})
1252}
1253
1254func TestCcLibrarySharedStubsDessertVersionConversion(t *testing.T) {
1255	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
1256		Description: "cc_library_shared converts dessert codename versions to numerical versions",
1257		Blueprint: `
1258cc_library_shared {
1259	name: "a",
1260	include_build_directory: false,
1261	stubs: {
1262		symbol_file: "a.map.txt",
1263		versions: [
1264			"Q",
1265			"R",
1266			"31",
1267		],
1268	},
1269}
1270cc_library_shared {
1271	name: "b",
1272	include_build_directory: false,
1273	stubs: {
1274		symbol_file: "b.map.txt",
1275		versions: [
1276			"Q",
1277			"R",
1278			"31",
1279			"current",
1280		],
1281	},
1282}
1283`,
1284		ExpectedBazelTargets: []string{
1285			makeCcStubSuiteTargets("a", AttrNameToString{
1286				"soname":               `"a.so"`,
1287				"source_library_label": `"//:a"`,
1288				"stubs_symbol_file":    `"a.map.txt"`,
1289				"stubs_versions": `[
1290        "29",
1291        "30",
1292        "31",
1293        "current",
1294    ]`,
1295			}),
1296			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
1297				"stubs_symbol_file": `"a.map.txt"`,
1298			}),
1299			makeCcStubSuiteTargets("b", AttrNameToString{
1300				"soname":               `"b.so"`,
1301				"source_library_label": `"//:b"`,
1302				"stubs_symbol_file":    `"b.map.txt"`,
1303				"stubs_versions": `[
1304        "29",
1305        "30",
1306        "31",
1307        "current",
1308    ]`,
1309			}),
1310			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
1311				"stubs_symbol_file": `"b.map.txt"`,
1312			}),
1313		},
1314	})
1315}
1316