1"""Copyright (C) 2023 The Android Open Source Project
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7     http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14"""
15
16load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
17
18def _test_linker_alignment_flag_impl(ctx):
19    """ Checks that linker alignment flag is present.
20
21    This test checks that the linker alignment flag is present for
22    arm and arm 64 targets but it is not present for x86 and x86_64 targets.
23    """
24
25    env = analysistest.begin(ctx)
26    actions = analysistest.target_actions(env)
27
28    for action in actions:
29        if action.mnemonic in ctx.attr.expected_action_mnemonics:
30            for flag in ctx.attr.expected_flags:
31                asserts.true(
32                    env,
33                    flag in action.argv,
34                    "%s action did not contain %s flag" % (
35                        action.mnemonic,
36                        flag,
37                    ),
38                )
39            for flag in ctx.attr.no_expected_flags:
40                asserts.false(
41                    env,
42                    flag in action.argv,
43                    "%s action contained unexpected flag %s" % (
44                        action.mnemonic,
45                        flag,
46                    ),
47                )
48        else:
49            for flag in ctx.attr.expected_flags:
50                if action.argv != None:
51                    asserts.false(
52                        env,
53                        flag in action.argv,
54                        "%s action contained unexpected flag %s" % (
55                            action.mnemonic,
56                            flag,
57                        ),
58                    )
59
60    return analysistest.end(env)
61
62test_attrs = {
63    "expected_flags": attr.string_list(
64        doc = "Flags expected to be supplied to the command line",
65    ),
66    "expected_action_mnemonics": attr.string_list(
67        doc = "Mnemonics for the actions that should have expected_flags",
68    ),
69    "no_expected_flags": attr.string_list(
70        doc = "Flags not expected to be supplied to the command line",
71    ),
72}
73
74linker_alignment_flag_arm_test = analysistest.make(
75    impl = _test_linker_alignment_flag_impl,
76    attrs = test_attrs,
77    config_settings = {
78        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm_for_testing",
79    },
80)
81
82linker_alignment_flag_arm64_test = analysistest.make(
83    impl = _test_linker_alignment_flag_impl,
84    attrs = test_attrs,
85    config_settings = {
86        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing",
87    },
88)
89
90custom_linker_alignment_flag_arm64_test = analysistest.make(
91    impl = _test_linker_alignment_flag_impl,
92    attrs = test_attrs,
93    config_settings = {
94        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_custom_linker_alignment",
95    },
96)
97
98custom_linker_alignment_flag_x86_64_test = analysistest.make(
99    impl = _test_linker_alignment_flag_impl,
100    attrs = test_attrs,
101    config_settings = {
102        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_x86_64_for_testing_custom_linker_alignment",
103    },
104)
105
106linker_alignment_flag_x86_test = analysistest.make(
107    impl = _test_linker_alignment_flag_impl,
108    attrs = test_attrs,
109    config_settings = {
110        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_x86_for_testing",
111    },
112)
113
114linker_alignment_flag_x86_64_test = analysistest.make(
115    impl = _test_linker_alignment_flag_impl,
116    attrs = test_attrs,
117    config_settings = {
118        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_x86_64_for_testing",
119    },
120)
121
122def _test_linker_alignment_flag_arm():
123    """ Checks that max-page-size flag is not present for arm targets.
124    """
125    name = "linker_alignment_flag_arm"
126    test_name = name + "_test"
127
128    native.cc_binary(
129        name = name,
130        srcs = ["foo.cpp"],
131        tags = ["manual"],
132    )
133
134    linker_alignment_flag_arm_test(
135        name = test_name,
136        target_under_test = name,
137        expected_action_mnemonics = ["CppLink"],
138        expected_flags = [],
139        no_expected_flags = [
140            "-Wl,-z,max-page-size=4096",
141            "-Wl,-z,max-page-size=16384",
142            "-Wl,-z,max-page-size=65536",
143        ],
144    )
145    return test_name
146
147def _test_linker_alignment_flag_arm64():
148    """ Checks that max-page-size flag is present for arm64 targets.
149    """
150    name = "linker_alignment_flag_arm64"
151    test_name = name + "_test"
152
153    native.cc_binary(
154        name = name,
155        srcs = ["foo.cpp"],
156        tags = ["manual"],
157    )
158
159    linker_alignment_flag_arm64_test(
160        name = test_name,
161        target_under_test = name,
162        expected_action_mnemonics = ["CppLink"],
163        expected_flags = [
164            "-Wl,-z,max-page-size=4096",
165        ],
166        no_expected_flags = [],
167    )
168    return test_name
169
170def _test_custom_linker_alignment_flag_arm64():
171    """ Checks that max-page-size flag has the custom alignment for arm64.
172    """
173    name = "custom_linker_alignment_flag_arm64"
174    test_name = name + "_test"
175
176    native.cc_binary(
177        name = name,
178        srcs = ["foo.cpp"],
179        tags = ["manual"],
180    )
181
182    custom_linker_alignment_flag_arm64_test(
183        name = test_name,
184        target_under_test = name,
185        expected_action_mnemonics = ["CppLink"],
186        expected_flags = [
187            "-Wl,-z,max-page-size=16384",
188        ],
189        no_expected_flags = [],
190    )
191    return test_name
192
193def _test_linker_alignment_flag_x86():
194    """ Checks that max-page-size flag is not present for x86.
195    """
196    name = "linker_alignment_flag_x86"
197    test_name = name + "_test"
198
199    native.cc_binary(
200        name = name,
201        srcs = ["foo.cpp"],
202        tags = ["manual"],
203    )
204
205    linker_alignment_flag_x86_test(
206        name = test_name,
207        target_under_test = name,
208        expected_action_mnemonics = ["CppCompile", "CppLink"],
209        expected_flags = [],
210        no_expected_flags = [
211            "-Wl,-z,max-page-size=4096",
212            "-Wl,-z,max-page-size=16384",
213            "-Wl,-z,max-page-size=65536",
214        ],
215    )
216    return test_name
217
218def _test_linker_alignment_flag_x86_64():
219    """ Checks that max-page-size flag is present for x86_64.
220    """
221    name = "linker_alignment_flag_x86_64"
222    test_name = name + "_test"
223
224    native.cc_binary(
225        name = name,
226        srcs = ["foo.cpp"],
227        tags = ["manual"],
228    )
229
230    linker_alignment_flag_x86_64_test(
231        name = test_name,
232        target_under_test = name,
233        expected_action_mnemonics = ["CppLink"],
234        expected_flags = [
235            "-Wl,-z,max-page-size=4096",
236        ],
237        no_expected_flags = [],
238    )
239    return test_name
240
241def _test_custom_linker_alignment_flag_x86_64():
242    """ Checks that max-page-size flag has the custom alignment for x86_64.
243    """
244    name = "custom_linker_alignment_flag_x86_64"
245    test_name = name + "_test"
246
247    native.cc_binary(
248        name = name,
249        srcs = ["foo.cpp"],
250        tags = ["manual"],
251    )
252
253    custom_linker_alignment_flag_x86_64_test(
254        name = test_name,
255        target_under_test = name,
256        expected_action_mnemonics = ["CppLink"],
257        expected_flags = [
258            "-Wl,-z,max-page-size=65536",
259        ],
260        no_expected_flags = [],
261    )
262    return test_name
263
264def cc_toolchain_features_linker_alignment_test_suite(name):
265    native.test_suite(
266        name = name,
267        tests = [
268            _test_linker_alignment_flag_arm(),
269            _test_linker_alignment_flag_arm64(),
270            _test_custom_linker_alignment_flag_arm64(),
271            _test_linker_alignment_flag_x86(),
272            _test_linker_alignment_flag_x86_64(),
273            _test_custom_linker_alignment_flag_x86_64(),
274        ],
275    )
276