• 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	// TODO(alexmarquez): Split out the preamble into common code?
28	soongCcLibrarySharedPreamble = soongCcLibraryStaticPreamble
29)
30
31func registerCcLibrarySharedModuleTypes(ctx android.RegistrationContext) {
32	cc.RegisterCCBuildComponents(ctx)
33	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
34	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
35	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
36}
37
38func runCcLibrarySharedTestCase(t *testing.T, tc bp2buildTestCase) {
39	t.Helper()
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 TestCcLibrarySharedVersionScript(t *testing.T) {
342	runCcLibrarySharedTestCase(t, bp2buildTestCase{
343		description: "cc_library_shared version script",
344		filesystem: map[string]string{
345			"version_script": "",
346		},
347		blueprint: soongCcLibrarySharedPreamble + `
348cc_library_shared {
349    name: "foo_shared",
350    version_script: "version_script",
351    include_build_directory: false,
352}`,
353		expectedBazelTargets: []string{
354			makeBazelTarget("cc_library_shared", "foo_shared", attrNameToString{
355				"additional_linker_inputs": `["version_script"]`,
356				"linkopts":                 `["-Wl,--version-script,$(location version_script)"]`,
357			}),
358		},
359	})
360}
361
362func TestCcLibrarySharedNoCrtTrue(t *testing.T) {
363	runCcLibrarySharedTestCase(t, bp2buildTestCase{
364		description: "cc_library_shared - nocrt: true emits attribute",
365		filesystem: map[string]string{
366			"impl.cpp": "",
367		},
368		blueprint: soongCcLibraryPreamble + `
369cc_library_shared {
370    name: "foo_shared",
371    srcs: ["impl.cpp"],
372    nocrt: true,
373    include_build_directory: false,
374}
375`,
376		expectedBazelTargets: []string{
377			makeBazelTarget("cc_library_shared", "foo_shared", attrNameToString{
378				"link_crt": `False`,
379				"srcs":     `["impl.cpp"]`,
380			}),
381		},
382	})
383}
384
385func TestCcLibrarySharedNoCrtFalse(t *testing.T) {
386	runCcLibrarySharedTestCase(t, bp2buildTestCase{
387		description: "cc_library_shared - nocrt: false doesn't emit attribute",
388		filesystem: map[string]string{
389			"impl.cpp": "",
390		},
391		blueprint: soongCcLibraryPreamble + `
392cc_library_shared {
393    name: "foo_shared",
394    srcs: ["impl.cpp"],
395    nocrt: false,
396    include_build_directory: false,
397}
398`,
399		expectedBazelTargets: []string{
400			makeBazelTarget("cc_library_shared", "foo_shared", attrNameToString{
401				"srcs": `["impl.cpp"]`,
402			}),
403		},
404	})
405}
406
407func TestCcLibrarySharedNoCrtArchVariant(t *testing.T) {
408	runCcLibrarySharedTestCase(t, bp2buildTestCase{
409		description: "cc_library_shared - nocrt in select",
410		filesystem: map[string]string{
411			"impl.cpp": "",
412		},
413		blueprint: soongCcLibraryPreamble + `
414cc_library_shared {
415    name: "foo_shared",
416    srcs: ["impl.cpp"],
417    arch: {
418        arm: {
419            nocrt: true,
420        },
421        x86: {
422            nocrt: false,
423        },
424    },
425    include_build_directory: false,
426}
427`,
428		expectedErr: fmt.Errorf("module \"foo_shared\": nocrt is not supported for arch variants"),
429	})
430}
431
432func TestCcLibrarySharedProto(t *testing.T) {
433	runCcLibrarySharedTestCase(t, bp2buildTestCase{
434		blueprint: soongCcProtoPreamble + `cc_library_shared {
435	name: "foo",
436	srcs: ["foo.proto"],
437	proto: {
438		export_proto_headers: true,
439	},
440	include_build_directory: false,
441}`,
442		expectedBazelTargets: []string{
443			makeBazelTarget("proto_library", "foo_proto", attrNameToString{
444				"srcs": `["foo.proto"]`,
445			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
446				"deps": `[":foo_proto"]`,
447			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
448				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
449				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
450			}),
451		},
452	})
453}
454
455func TestCcLibrarySharedUseVersionLib(t *testing.T) {
456	runCcLibrarySharedTestCase(t, bp2buildTestCase{
457		blueprint: soongCcProtoPreamble + `cc_library_shared {
458        name: "foo",
459        use_version_lib: true,
460        include_build_directory: false,
461}`,
462		expectedBazelTargets: []string{
463			makeBazelTarget("cc_library_shared", "foo", attrNameToString{
464				"use_version_lib": "True",
465			}),
466		},
467	})
468}
469
470func TestCcLibrarySharedStubs(t *testing.T) {
471	runCcLibrarySharedTestCase(t, bp2buildTestCase{
472		description:                "cc_library_shared stubs",
473		moduleTypeUnderTest:        "cc_library_shared",
474		moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
475		dir:                        "foo/bar",
476		filesystem: map[string]string{
477			"foo/bar/Android.bp": `
478cc_library_shared {
479	name: "a",
480	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
481	bazel_module: { bp2build_available: true },
482	include_build_directory: false,
483}
484`,
485		},
486		blueprint: soongCcLibraryPreamble,
487		expectedBazelTargets: []string{makeBazelTarget("cc_library_shared", "a", attrNameToString{
488			"stubs_symbol_file": `"a.map.txt"`,
489			"stubs_versions": `[
490        "28",
491        "29",
492        "current",
493    ]`,
494		}),
495		},
496	},
497	)
498}
499