• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2022 The Android Open Source Project
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
15load("@bazel_skylib//lib:paths.bzl", "paths")
16load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
17load("//build/bazel/rules/cc:cc_binary.bzl", "cc_binary")
18load("//build/bazel/rules/cc:cc_library_headers.bzl", "cc_library_headers")
19load("//build/bazel/rules/cc:cc_library_shared.bzl", "cc_library_shared")
20load("//build/bazel/rules/cc:cc_library_static.bzl", "cc_library_static")
21load("//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", "cc_prebuilt_library_static")
22load(
23    "//build/bazel/rules/test_common:flags.bzl",
24    "action_flags_absent_for_mnemonic_test",
25    "action_flags_present_only_for_mnemonic_test",
26)
27load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path", "get_package_dir_based_path")
28load("//build/bazel/rules/test_common:rules.bzl", "expect_failure_test")
29load(":cc_library_common_test.bzl", "target_provides_androidmk_info_test")
30
31def _cc_library_static_propagating_compilation_context_test_impl(ctx):
32    env = analysistest.begin(ctx)
33    target = analysistest.target_under_test(env)
34    cc_info = target[CcInfo]
35    compilation_context = cc_info.compilation_context
36
37    header_paths = [f.path for f in compilation_context.headers.to_list()]
38    for hdr in ctx.files.expected_hdrs:
39        asserts.true(
40            env,
41            hdr.path in header_paths,
42            "Did not find {hdr} in includes: {hdrs}.".format(hdr = hdr, hdrs = compilation_context.headers),
43        )
44
45    for hdr in ctx.files.expected_absent_hdrs:
46        asserts.true(
47            env,
48            hdr not in header_paths,
49            "Found {hdr} in includes: {hdrs}, should not be present.".format(hdr = hdr, hdrs = compilation_context.headers),
50        )
51
52    for include in ctx.attr.expected_includes:
53        absolute_include = get_package_dir_based_path(env, include)
54        asserts.true(
55            env,
56            absolute_include in compilation_context.includes.to_list(),
57            "Did not find {include} in includes: {includes}.".format(include = include, includes = compilation_context.includes),
58        )
59
60    for include in ctx.attr.expected_absent_includes:
61        absolute_include = get_package_dir_based_path(env, include)
62        asserts.true(
63            env,
64            absolute_include not in compilation_context.includes.to_list(),
65            "Found {include} in includes: {includes}, was expected to be absent".format(include = include, includes = compilation_context.includes),
66        )
67
68    for include in ctx.attr.expected_system_includes:
69        absolute_include = get_package_dir_based_path(env, include)
70        asserts.true(
71            env,
72            absolute_include in compilation_context.system_includes.to_list(),
73            "Did not find {include} in system includes: {includes}.".format(include = include, includes = compilation_context.system_includes),
74        )
75
76    for include in ctx.attr.expected_absent_system_includes:
77        absolute_include = get_package_dir_based_path(env, include)
78        asserts.true(
79            env,
80            absolute_include not in compilation_context.system_includes.to_list(),
81            "Found {include} in system includes: {includes}, was expected to be absent".format(include = include, includes = compilation_context.system_includes),
82        )
83
84    return analysistest.end(env)
85
86_cc_library_static_propagating_compilation_context_test = analysistest.make(
87    _cc_library_static_propagating_compilation_context_test_impl,
88    attrs = {
89        "expected_hdrs": attr.label_list(),
90        "expected_absent_hdrs": attr.label_list(),
91        "expected_includes": attr.string_list(),
92        "expected_absent_includes": attr.string_list(),
93        "expected_system_includes": attr.string_list(),
94        "expected_absent_system_includes": attr.string_list(),
95    },
96)
97
98def _cc_library_static_propagates_deps():
99    name = "_cc_library_static_propagates_deps"
100    dep_name = name + "_dep"
101    test_name = name + "_test"
102
103    cc_library_static(
104        name = dep_name,
105        hdrs = [":hdr"],
106        export_includes = ["a/b/c"],
107        export_system_includes = ["d/e/f"],
108        tags = ["manual"],
109    )
110
111    cc_library_static(
112        name = name,
113        deps = [dep_name],
114        tags = ["manual"],
115    )
116
117    _cc_library_static_propagating_compilation_context_test(
118        name = test_name,
119        target_under_test = name,
120        expected_hdrs = [":hdr"],
121        expected_includes = ["a/b/c"],
122        expected_system_includes = ["d/e/f"],
123    )
124
125    return test_name
126
127def _cc_library_static_propagates_whole_archive_deps():
128    name = "_cc_library_static_propagates_whole_archive_deps"
129    dep_name = name + "_dep"
130    test_name = name + "_test"
131
132    cc_library_static(
133        name = dep_name,
134        hdrs = [":hdr"],
135        export_includes = ["a/b/c"],
136        export_system_includes = ["d/e/f"],
137        tags = ["manual"],
138    )
139
140    cc_library_static(
141        name = name,
142        whole_archive_deps = [dep_name],
143        tags = ["manual"],
144    )
145
146    _cc_library_static_propagating_compilation_context_test(
147        name = test_name,
148        target_under_test = name,
149        expected_hdrs = [":hdr"],
150        expected_includes = ["a/b/c"],
151        expected_system_includes = ["d/e/f"],
152    )
153
154    return test_name
155
156def _cc_library_static_propagates_dynamic_deps():
157    name = "_cc_library_static_propagates_dynamic_deps"
158    dep_name = name + "_dep"
159    test_name = name + "_test"
160
161    cc_library_shared(
162        name = dep_name,
163        hdrs = [":hdr"],
164        export_includes = ["a/b/c"],
165        export_system_includes = ["d/e/f"],
166        tags = ["manual"],
167    )
168
169    cc_library_static(
170        name = name,
171        dynamic_deps = [dep_name],
172        tags = ["manual"],
173    )
174
175    _cc_library_static_propagating_compilation_context_test(
176        name = test_name,
177        target_under_test = name,
178        expected_hdrs = [":hdr"],
179        expected_includes = ["a/b/c"],
180        expected_system_includes = ["d/e/f"],
181    )
182
183    return test_name
184
185def _cc_library_static_does_not_propagate_implementation_deps():
186    name = "_cc_library_static_does_not_propagate_implementation_deps"
187    dep_name = name + "_dep"
188    test_name = name + "_test"
189
190    cc_library_static(
191        name = dep_name,
192        hdrs = [":hdr"],
193        export_includes = ["a/b/c"],
194        export_system_includes = ["d/e/f"],
195        tags = ["manual"],
196    )
197
198    cc_library_static(
199        name = name,
200        implementation_deps = [dep_name],
201        tags = ["manual"],
202    )
203
204    _cc_library_static_propagating_compilation_context_test(
205        name = test_name,
206        target_under_test = name,
207        expected_absent_hdrs = [":hdr"],
208        expected_absent_includes = ["a/b/c"],
209        expected_absent_system_includes = ["d/e/f"],
210    )
211
212    return test_name
213
214def _cc_library_static_does_not_propagate_implementation_whole_archive_deps():
215    name = "_cc_library_static_does_not_propagate_implementation_whole_archive_deps"
216    dep_name = name + "_dep"
217    test_name = name + "_test"
218
219    cc_library_static(
220        name = dep_name,
221        hdrs = [":hdr"],
222        export_includes = ["a/b/c"],
223        export_system_includes = ["d/e/f"],
224        tags = ["manual"],
225    )
226
227    cc_library_static(
228        name = name,
229        implementation_whole_archive_deps = [dep_name],
230        tags = ["manual"],
231    )
232
233    _cc_library_static_propagating_compilation_context_test(
234        name = test_name,
235        target_under_test = name,
236        expected_absent_hdrs = [":hdr"],
237        expected_absent_includes = ["a/b/c"],
238        expected_absent_system_includes = ["d/e/f"],
239    )
240
241    return test_name
242
243def _cc_library_static_does_not_propagate_implementation_dynamic_deps():
244    name = "_cc_library_static_does_not_propagate_implementation_dynamic_deps"
245    dep_name = name + "_dep"
246    test_name = name + "_test"
247
248    cc_library_shared(
249        name = dep_name,
250        hdrs = [":hdr"],
251        export_includes = ["a/b/c"],
252        export_system_includes = ["d/e/f"],
253        tags = ["manual"],
254    )
255
256    cc_library_static(
257        name = name,
258        implementation_dynamic_deps = [dep_name],
259        tags = ["manual"],
260    )
261
262    _cc_library_static_propagating_compilation_context_test(
263        name = test_name,
264        target_under_test = name,
265        expected_absent_hdrs = [":hdr"],
266        expected_absent_includes = ["a/b/c"],
267        expected_absent_system_includes = ["d/e/f"],
268    )
269
270    return test_name
271
272def _cc_rules_do_not_allow_absolute_includes():
273    name = "cc_rules_do_not_allow_absolute_includes"
274    test_names = []
275
276    DISALLOWED_INCLUDE_DIRS = [
277        "art",
278        "art/libnativebridge",
279        "art/libnativeloader",
280        "libcore",
281        "libnativehelper",
282        "external/apache-harmony",
283        "external/apache-xml",
284        "external/boringssl",
285        "external/bouncycastle",
286        "external/conscrypt",
287        "external/icu",
288        "external/okhttp",
289        "external/vixl",
290        "external/wycheproof",
291    ]
292
293    for include_dir in DISALLOWED_INCLUDE_DIRS:
294        binary_name = name + "_binary" + "_" + include_dir
295        library_headers_name = name + "_library_headers" + "_" + include_dir
296        library_shared_name = name + "_library_shared" + "_" + include_dir
297        library_static_name = name + "_library_static" + "_" + include_dir
298
299        cc_binary(
300            name = binary_name,
301            absolute_includes = [include_dir],
302            tags = ["manual"],
303        )
304        cc_library_headers(
305            name = library_headers_name,
306            absolute_includes = [include_dir],
307            tags = ["manual"],
308        )
309        cc_library_shared(
310            name = library_shared_name,
311            absolute_includes = [include_dir],
312            tags = ["manual"],
313        )
314        cc_library_static(
315            name = library_static_name,
316            absolute_includes = [include_dir],
317            tags = ["manual"],
318        )
319
320        for target in [
321            binary_name,
322            library_headers_name,
323            library_static_name,
324            library_shared_name,
325        ]:
326            test_name = target + "_" + include_dir + "_test"
327            test_names.append(test_name)
328            expect_failure_test(
329                name = test_name,
330                target_under_test = target,
331            )
332
333    return test_names
334
335def _cc_library_static_links_against_prebuilt_library_test_impl(ctx):
336    env = analysistest.begin(ctx)
337    actions = analysistest.target_actions(env)
338
339    asserts.equals(env, 2, len(actions), "Expected actions, got %s" % actions)
340
341    argv = actions[0].argv
342    expected_output_action1 = get_output_and_package_dir_based_path(env, "libcc_library_static_links_against_prebuilt_library_objs_only.a")
343    asserts.equals(env, 5, len(argv))
344    asserts.equals(env, "crsPD", argv[1])
345    asserts.equals(env, expected_output_action1, argv[2])
346    asserts.equals(env, get_output_and_package_dir_based_path(env, paths.join("_objs", "cc_library_static_links_against_prebuilt_library_cpp", "bar.o")), argv[3])
347    asserts.equals(env, "--format=gnu", argv[4])
348
349    argv = actions[1].argv
350    asserts.equals(env, 6, len(argv))
351    asserts.equals(env, "cqsL", argv[1])
352    asserts.equals(env, get_output_and_package_dir_based_path(env, "libcc_library_static_links_against_prebuilt_library.a"), argv[2])
353    asserts.equals(env, "--format=gnu", argv[3])
354    asserts.equals(env, expected_output_action1, argv[4])
355    asserts.equals(env, get_package_dir_based_path(env, "foo.a"), argv[5])
356
357    return analysistest.end(env)
358
359_cc_library_static_links_against_prebuilt_library_test = analysistest.make(_cc_library_static_links_against_prebuilt_library_test_impl)
360
361def _cc_library_static_links_against_prebuilt_library():
362    name = "cc_library_static_links_against_prebuilt_library"
363    test_name = name + "_test"
364    dep_name = name + "_dep"
365
366    cc_prebuilt_library_static(
367        name = dep_name,
368        static_library = "foo.a",
369        tags = ["manual"],
370    )
371
372    cc_library_static(
373        name = name,
374        srcs = ["bar.c"],
375        whole_archive_deps = [dep_name],
376        tags = ["manual"],
377    )
378
379    _cc_library_static_links_against_prebuilt_library_test(
380        name = test_name,
381        target_under_test = name,
382    )
383
384    return test_name
385
386def _cc_library_static_linking_object_ordering_test_impl(ctx):
387    env = analysistest.begin(ctx)
388    actions = analysistest.target_actions(env)
389
390    asserts.equals(env, 1, len(actions), "Expected actions, got %s" % actions)
391
392    outputs = actions[0].outputs.to_list()
393    argv = actions[0].argv
394    asserts.equals(env, 4 + len(ctx.attr.expected_objects_in_order), len(argv))
395    asserts.equals(env, "crsPD", argv[1])
396    asserts.equals(env, outputs[0].path, argv[2])
397
398    for i in range(len(ctx.attr.expected_objects_in_order)):
399        obj = ctx.attr.expected_objects_in_order[i]
400        asserts.equals(env, obj, paths.basename(argv[3 + i]))
401
402    asserts.equals(env, "--format=gnu", argv[-1])
403
404    return analysistest.end(env)
405
406_cc_library_static_linking_object_ordering_test = analysistest.make(
407    _cc_library_static_linking_object_ordering_test_impl,
408    attrs = {
409        "expected_objects_in_order": attr.string_list(),
410    },
411)
412
413def _cc_library_static_whole_archive_deps_objects_precede_target_objects():
414    name = "_cc_library_static_whole_archive_deps_objects_precede_target_objects"
415    dep_name = name + "_dep"
416    test_name = name + "_test"
417
418    cc_library_static(
419        name = dep_name,
420        srcs = ["first.c"],
421        tags = ["manual"],
422    )
423
424    cc_library_static(
425        name = name,
426        srcs = ["second.c"],
427        whole_archive_deps = [dep_name],
428        tags = ["manual"],
429    )
430
431    _cc_library_static_linking_object_ordering_test(
432        name = test_name,
433        target_under_test = name,
434        expected_objects_in_order = [
435            "first.o",
436            "second.o",
437        ],
438    )
439
440    return test_name
441
442def _cc_library_static_provides_androidmk_info():
443    name = "cc_library_static_provides_androidmk_info"
444    dep_name = name + "_static_dep"
445    whole_archive_dep_name = name + "_whole_archive_dep"
446    dynamic_dep_name = name + "_dynamic_dep"
447    test_name = name + "_test"
448
449    cc_library_static(
450        name = dep_name,
451        srcs = ["foo.c"],
452        tags = ["manual"],
453    )
454    cc_library_static(
455        name = whole_archive_dep_name,
456        srcs = ["foo.c"],
457        tags = ["manual"],
458    )
459    cc_library_shared(
460        name = dynamic_dep_name,
461        srcs = ["foo.c"],
462        tags = ["manual"],
463    )
464    cc_library_static(
465        name = name,
466        srcs = ["foo.cc"],
467        deps = [dep_name],
468        whole_archive_deps = [whole_archive_dep_name],
469        dynamic_deps = [dynamic_dep_name],
470        tags = ["manual"],
471    )
472    android_test_name = test_name + "_android"
473    linux_test_name = test_name + "_linux"
474    target_provides_androidmk_info_test(
475        name = android_test_name,
476        target_under_test = name,
477        expected_static_libs = [dep_name, "libc++_static", "libc++demangle"],
478        expected_whole_static_libs = [whole_archive_dep_name],
479        expected_shared_libs = [dynamic_dep_name, "libc", "libdl", "libm"],
480        target_compatible_with = ["//build/bazel/platforms/os:android"],
481    )
482    target_provides_androidmk_info_test(
483        name = linux_test_name,
484        target_under_test = name,
485        expected_static_libs = [dep_name, "libc++_static"],
486        expected_whole_static_libs = [whole_archive_dep_name],
487        expected_shared_libs = [dynamic_dep_name],
488        target_compatible_with = ["//build/bazel/platforms/os:linux"],
489    )
490    return [
491        android_test_name,
492        linux_test_name,
493    ]
494
495def _cc_library_static_link_action_should_not_have_arch_cflags():
496    name = "cc_library_static_link_action_should_not_have_cflags"
497    cpp_compile_test_name = name + "_CppCompile_test"
498    cpp_link_test_name = name + "_CppLink_test"
499
500    # https://cs.android.com/android/platform/build/soong/+/master:cc/config/arm_device.go;l=57-59;drc=de7c7847e7e028d46fdff8268689f30163c4c231
501    arm_armv7_a_cflags = ["-march=armv7-a", "-mfloat-abi=softfp"]
502
503    cc_library_static(
504        name = name,
505        srcs = ["foo.cpp"],
506        tags = ["manual"],
507    )
508
509    action_flags_present_only_for_mnemonic_test(
510        name = cpp_compile_test_name,
511        target_under_test = name + "_cpp",
512        mnemonics = ["CppCompile"],
513        expected_flags = arm_armv7_a_cflags,
514        target_compatible_with = [
515            "//build/bazel/platforms/os:android",
516            "//build/bazel/platforms/arch/variants:armv7-a-neon",
517        ],
518    )
519
520    action_flags_absent_for_mnemonic_test(
521        name = cpp_link_test_name,
522        target_under_test = name,
523        mnemonics = ["CppLink"],
524        expected_absent_flags = arm_armv7_a_cflags,
525        target_compatible_with = [
526            "//build/bazel/platforms/os:android",
527            "//build/bazel/platforms/arch/variants:armv7-a-neon",
528        ],
529    )
530
531    return [
532        cpp_compile_test_name,
533        cpp_link_test_name,
534    ]
535
536def _cc_library_static_defines_do_not_check_manual_binder_interfaces():
537    name = "_cc_library_static_defines_do_not_check_manual_binder_interfaces"
538    cpp_lib_name = name + "_cpp"
539    cpp_test_name = cpp_lib_name + "_test"
540    c_lib_name = name + "_c"
541    c_test_name = c_lib_name + "_test"
542
543    cc_library_static(
544        name = name,
545        srcs = ["a.cpp"],
546        srcs_c = ["b.c"],
547        tags = ["manual"],
548    )
549    action_flags_present_only_for_mnemonic_test(
550        name = cpp_test_name,
551        target_under_test = cpp_lib_name,
552        mnemonics = ["CppCompile"],
553        expected_flags = [
554            "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES",
555        ],
556    )
557    action_flags_present_only_for_mnemonic_test(
558        name = c_test_name,
559        target_under_test = c_lib_name,
560        mnemonics = ["CppCompile"],
561        expected_flags = [
562            "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES",
563        ],
564    )
565
566    non_allowlisted_package_cpp_name = name + "_non_allowlisted_package_cpp"
567    action_flags_absent_for_mnemonic_test(
568        name = non_allowlisted_package_cpp_name,
569        target_under_test = "//build/bazel/examples/cc:foo_static_cpp",
570        mnemonics = ["CppCompile"],
571        expected_absent_flags = [
572            "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES",
573        ],
574    )
575
576    return [
577        cpp_test_name,
578        c_test_name,
579        non_allowlisted_package_cpp_name,
580    ]
581
582def cc_library_static_test_suite(name):
583    native.genrule(name = "hdr", cmd = "null", outs = ["f.h"], tags = ["manual"])
584
585    native.test_suite(
586        name = name,
587        tests = [
588            _cc_library_static_propagates_deps(),
589            _cc_library_static_propagates_whole_archive_deps(),
590            _cc_library_static_propagates_dynamic_deps(),
591            _cc_library_static_does_not_propagate_implementation_deps(),
592            _cc_library_static_does_not_propagate_implementation_whole_archive_deps(),
593            _cc_library_static_does_not_propagate_implementation_dynamic_deps(),
594            _cc_library_static_links_against_prebuilt_library(),
595            _cc_library_static_whole_archive_deps_objects_precede_target_objects(),
596        ] + (
597            _cc_rules_do_not_allow_absolute_includes() +
598            _cc_library_static_provides_androidmk_info() +
599            _cc_library_static_link_action_should_not_have_arch_cflags() +
600            _cc_library_static_defines_do_not_check_manual_binder_interfaces()
601        ),
602    )
603