• 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:unittest.bzl", "analysistest", "asserts")
16load(":cc_binary.bzl", "cc_binary")
17load(":cc_library_common_test.bzl", "target_provides_androidmk_info_test")
18load(":cc_library_shared.bzl", "cc_library_shared")
19load(":cc_library_static.bzl", "cc_library_static")
20
21def strip_test_assert_flags(env, strip_action, strip_flags):
22    # Extract these flags from strip_action (for example):
23    # build/soong/scripts/strip.sh --keep-symbols --add-gnu-debuglink -i <in> -o <out> -d <out>.d
24    #                              ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
25    flag_start_idx = 1  # starts after the strip.sh executable
26    flag_end_idx = strip_action.argv.index("-i")  # end of the flags
27    asserts.equals(
28        env,
29        strip_action.argv[flag_start_idx:flag_end_idx],
30        strip_flags,
31    )
32
33def _cc_binary_strip_test(ctx):
34    env = analysistest.begin(ctx)
35    actions = analysistest.target_actions(env)
36    filtered_actions = [a for a in actions if a.mnemonic == "CcStrip"]
37    on_target = ctx.target_platform_has_constraint(
38        ctx.attr._android_constraint[platform_common.ConstraintValueInfo],
39    )
40    if ctx.attr.strip_flags or on_target:
41        # expected to find strip flags, so look for a CcStrip action.
42        asserts.true(
43            env,
44            len(filtered_actions) == 1,
45            "expected to find an action with CcStrip mnemonic in %s" % actions,
46        )
47        if ctx.attr.strip_flags or not on_target:
48            strip_test_assert_flags(env, filtered_actions[0], ctx.attr.strip_flags)
49        return analysistest.end(env)
50    else:
51        asserts.true(
52            env,
53            len(filtered_actions) == 0,
54            "expected to not find an action with CcStrip mnemonic in %s" % actions,
55        )
56        return analysistest.end(env)
57
58cc_binary_strip_test = analysistest.make(
59    _cc_binary_strip_test,
60    attrs = {
61        "strip_flags": attr.string_list(),
62        "_android_constraint": attr.label(default = Label("//build/bazel/platforms/os:android")),
63    },
64)
65
66def _cc_binary_strip_default():
67    name = "cc_binary_strip_default"
68    test_name = name + "_test"
69
70    cc_binary(
71        name = name,
72        srcs = ["main.cc"],
73        tags = ["manual"],
74    )
75
76    cc_binary_strip_test(
77        name = test_name,
78        target_under_test = name,
79        strip_flags = [],
80    )
81
82    return test_name
83
84def _cc_binary_strip_keep_symbols():
85    name = "cc_binary_strip_keep_symbols"
86    test_name = name + "_test"
87
88    cc_binary(
89        name = name,
90        srcs = ["main.cc"],
91        tags = ["manual"],
92        strip = {"keep_symbols": True},
93    )
94
95    cc_binary_strip_test(
96        name = test_name,
97        target_under_test = name,
98        strip_flags = [
99            "--keep-symbols",
100            "--add-gnu-debuglink",
101        ],
102    )
103
104    return test_name
105
106def _cc_binary_strip_keep_symbols_and_debug_frame():
107    name = "cc_binary_strip_keep_symbols_and_debug_frame"
108    test_name = name + "_test"
109
110    cc_binary(
111        name = name,
112        srcs = ["main.cc"],
113        tags = ["manual"],
114        strip = {"keep_symbols_and_debug_frame": True},
115    )
116
117    cc_binary_strip_test(
118        name = test_name,
119        target_under_test = name,
120        strip_flags = [
121            "--keep-symbols-and-debug-frame",
122            "--add-gnu-debuglink",
123        ],
124    )
125
126    return test_name
127
128def _cc_binary_strip_keep_symbols_list():
129    name = "cc_binary_strip_keep_symbols_list"
130    test_name = name + "_test"
131
132    cc_binary(
133        name = name,
134        srcs = ["main.cc"],
135        tags = ["manual"],
136        strip = {"keep_symbols_list": ["foo", "bar"]},
137    )
138
139    cc_binary_strip_test(
140        name = test_name,
141        target_under_test = name,
142        strip_flags = [
143            "-kfoo,bar",
144            "--add-gnu-debuglink",
145        ],
146    )
147
148    return test_name
149
150def _cc_binary_strip_all():
151    name = "cc_binary_strip_all"
152    test_name = name + "_test"
153
154    cc_binary(
155        name = name,
156        srcs = ["main.cc"],
157        tags = ["manual"],
158        strip = {"all": True},
159    )
160
161    cc_binary_strip_test(
162        name = test_name,
163        target_under_test = name,
164        strip_flags = [
165            "--add-gnu-debuglink",
166        ],
167    )
168
169    return test_name
170
171def _cc_binary_suffix_test_impl(ctx):
172    env = analysistest.begin(ctx)
173    target = analysistest.target_under_test(env)
174    info = target[DefaultInfo]
175    suffix = ctx.attr.suffix
176
177    outputs = info.files.to_list()
178    asserts.true(
179        env,
180        len(outputs) == 1,
181        "Expected 1 output file; got %s" % outputs,
182    )
183    out = outputs[0].path
184    asserts.true(
185        env,
186        out.endswith(suffix),
187        "Expected output filename to end in `%s`; it was instead %s" % (suffix, out),
188    )
189
190    return analysistest.end(env)
191
192cc_binary_suffix_test = analysistest.make(
193    _cc_binary_suffix_test_impl,
194    attrs = {"suffix": attr.string()},
195)
196
197def _cc_binary_suffix():
198    name = "cc_binary_suffix"
199    test_name = name + "_test"
200    suffix = "-suf"
201
202    cc_binary(
203        name,
204        srcs = ["src.cc"],
205        tags = ["manual"],
206        suffix = suffix,
207    )
208    cc_binary_suffix_test(
209        name = test_name,
210        target_under_test = name,
211        suffix = suffix,
212    )
213    return test_name
214
215def _cc_binary_empty_suffix():
216    name = "cc_binary_empty_suffix"
217    test_name = name + "_test"
218
219    cc_binary(
220        name,
221        srcs = ["src.cc"],
222        tags = ["manual"],
223    )
224    cc_binary_suffix_test(
225        name = test_name,
226        target_under_test = name,
227    )
228    return test_name
229
230def _cc_binary_provides_androidmk_info():
231    name = "cc_binary_provides_androidmk_info"
232    dep_name = name + "_static_dep"
233    whole_archive_dep_name = name + "_whole_archive_dep"
234    dynamic_dep_name = name + "_dynamic_dep"
235    test_name = name + "_test"
236
237    cc_library_static(
238        name = dep_name,
239        srcs = ["foo.c"],
240        tags = ["manual"],
241    )
242    cc_library_static(
243        name = whole_archive_dep_name,
244        srcs = ["foo.c"],
245        tags = ["manual"],
246    )
247    cc_library_shared(
248        name = dynamic_dep_name,
249        srcs = ["foo.c"],
250        tags = ["manual"],
251    )
252    cc_binary(
253        name = name,
254        srcs = ["foo.cc"],
255        deps = [dep_name],
256        whole_archive_deps = [whole_archive_dep_name],
257        dynamic_deps = [dynamic_dep_name],
258        tags = ["manual"],
259    )
260    android_test_name = test_name + "_android"
261    linux_test_name = test_name + "_linux"
262    target_provides_androidmk_info_test(
263        name = android_test_name,
264        target_under_test = name,
265        expected_static_libs = [dep_name, "libc++demangle", "libunwind"],
266        expected_whole_static_libs = [whole_archive_dep_name],
267        expected_shared_libs = [dynamic_dep_name, "libc++", "libc", "libdl", "libm"],
268        target_compatible_with = ["//build/bazel/platforms/os:android"],
269    )
270    target_provides_androidmk_info_test(
271        name = linux_test_name,
272        target_under_test = name,
273        expected_static_libs = [dep_name],
274        expected_whole_static_libs = [whole_archive_dep_name],
275        expected_shared_libs = [dynamic_dep_name, "libc++"],
276        target_compatible_with = ["//build/bazel/platforms/os:linux"],
277    )
278    return [
279        android_test_name,
280        linux_test_name,
281    ]
282
283def cc_binary_test_suite(name):
284    native.test_suite(
285        name = name,
286        tests = [
287            _cc_binary_strip_default(),
288            _cc_binary_strip_keep_symbols(),
289            _cc_binary_strip_keep_symbols_and_debug_frame(),
290            _cc_binary_strip_keep_symbols_list(),
291            _cc_binary_strip_all(),
292            _cc_binary_suffix(),
293            _cc_binary_empty_suffix(),
294        ] + _cc_binary_provides_androidmk_info(),
295    )
296