xref: /aosp_15_r20/build/bazel/rules/cc/cc_binary.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1# Copyright (C) 2021 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(
16    ":cc_library_common.bzl",
17    "add_lists_defaulting_to_none",
18    "parse_sdk_version",
19    "sanitizer_deps",
20    "system_dynamic_deps_defaults",
21    "system_static_deps_defaults",
22)
23load(":cc_library_static.bzl", "cc_library_static")
24load(":stl.bzl", "stl_info_from_attr")
25load(":stripped_cc_common.bzl", "stripped_binary", "stripped_test")
26load(":versioned_cc_common.bzl", "versioned_binary")
27
28def cc_binary(
29        name,
30        stem = "",
31        suffix = "",
32        dynamic_deps = [],
33        srcs = [],
34        srcs_c = [],
35        srcs_as = [],
36        copts = [],
37        cppflags = [],
38        conlyflags = [],
39        asflags = [],
40        deps = [],
41        whole_archive_deps = [],
42        system_deps = None,
43        runtime_deps = [],
44        export_includes = [],  # @unused
45        export_system_includes = [],  # @unused
46        local_includes = [],
47        absolute_includes = [],
48        linkshared = True,
49        linkopts = [],
50        rtti = False,
51        use_libcrt = True,
52        stl = "",
53        cpp_std = "",
54        additional_linker_inputs = None,
55        additional_compiler_inputs = [],
56        strip = {},
57        features = [],
58        target_compatible_with = [],
59        sdk_version = "",  # @unused
60        min_sdk_version = "",
61        use_version_lib = False,
62        tags = [],
63        generate_cc_test = False,
64        tidy = None,
65        tidy_checks = None,
66        tidy_checks_as_errors = None,
67        tidy_flags = None,
68        tidy_disabled_srcs = None,
69        tidy_timeout_srcs = None,
70        native_coverage = True,
71        **kwargs):
72    "Bazel macro to correspond with the cc_binary Soong module."
73
74    root_name = name + "__internal_root"
75    unstripped_name = name + "_unstripped"
76
77    toolchain_features = []
78    toolchain_features.append("cc_binary")
79    toolchain_features.extend(["-pic", "pie"])
80    if linkshared:
81        toolchain_features.extend(["dynamic_executable", "dynamic_linker"])
82    else:
83        toolchain_features.extend(["-dynamic_executable", "-dynamic_linker", "static_executable", "static_flag"])
84
85    if not use_libcrt:
86        toolchain_features.append("-use_libcrt")
87
88    if min_sdk_version:
89        toolchain_features += parse_sdk_version(min_sdk_version) + ["-sdk_version_default"]
90
91    system_dynamic_deps = []
92    system_static_deps = []
93    if system_deps == None:
94        if linkshared:
95            system_deps = system_dynamic_deps_defaults
96        else:
97            system_deps = system_static_deps_defaults
98
99    if linkshared:
100        system_dynamic_deps = system_deps
101    else:
102        system_static_deps = system_deps
103
104    if not native_coverage:
105        toolchain_features.append("-coverage")
106    else:
107        toolchain_features += select({
108            "//build/bazel/rules/cc:android_coverage_lib_flag": ["android_coverage_lib"],
109            "//conditions:default": [],
110        })
111
112        # TODO(b/233660582): deal with the cases where the default lib shouldn't be used
113        deps = deps + select({
114            "//build/bazel/rules/cc:android_coverage_lib_flag": ["//system/extras/toolchain-extras:libprofile-clang-extras"],
115            "//build/bazel/rules/cc:android_coverage_lib_flag_cfi": ["//system/extras/toolchain-extras:libprofile-clang-extras_cfi_support"],
116            "//conditions:default": [],
117        })
118
119    # add the passed in features last, the reason is that it might include select statement so
120    # using append() function will not work, but the formatter will insist you to use that for
121    # adding single element.
122    toolchain_features += features
123
124    stl_info = stl_info_from_attr(stl, linkshared, is_binary = True)
125    linkopts = linkopts + stl_info.linkopts
126    copts = copts + stl_info.cppflags
127
128    # The static library at the root of the cc_binary.
129    cc_library_static(
130        name = root_name,
131        absolute_includes = absolute_includes,
132        # alwayslink = True because the compiled objects from cc_library.srcs is expected
133        # to always be linked into the binary itself later (otherwise, why compile them at
134        # the cc_binary level?).
135        #
136        # Concretely, this makes this static library to be wrapped in the --whole_archive
137        # block when linking the cc_binary later.
138        alwayslink = True,
139        asflags = asflags,
140        conlyflags = conlyflags,
141        copts = copts,
142        cpp_std = cpp_std,
143        cppflags = cppflags,
144        deps = deps + stl_info.static_deps + system_static_deps,
145        whole_archive_deps = whole_archive_deps,
146        dynamic_deps = dynamic_deps + stl_info.shared_deps,
147        features = toolchain_features,
148        local_includes = local_includes,
149        rtti = rtti,
150        srcs = srcs,
151        srcs_as = srcs_as,
152        srcs_c = srcs_c,
153        stl = "none",
154        system_dynamic_deps = system_dynamic_deps,
155        target_compatible_with = target_compatible_with,
156        tags = ["manual"],
157        tidy = tidy,
158        tidy_checks = tidy_checks,
159        tidy_checks_as_errors = tidy_checks_as_errors,
160        tidy_flags = tidy_flags,
161        tidy_disabled_srcs = tidy_disabled_srcs,
162        tidy_timeout_srcs = tidy_timeout_srcs,
163        native_coverage = native_coverage,
164        additional_compiler_inputs = additional_compiler_inputs,
165    )
166
167    binary_dynamic_deps = add_lists_defaulting_to_none(
168        dynamic_deps,
169        system_dynamic_deps,
170        stl_info.shared_deps,
171    )
172
173    sanitizer_deps_name = name + "_sanitizer_deps"
174    sanitizer_deps(
175        name = sanitizer_deps_name,
176        dep = root_name,
177        tags = ["manual"],
178    )
179
180    # cc_test and cc_binary are almost identical rules, so fork the top level
181    # rule classes here.
182    unstripped_cc_rule = native.cc_binary
183    stripped_cc_rule = stripped_binary
184    if generate_cc_test:
185        unstripped_cc_rule = native.cc_test
186        stripped_cc_rule = stripped_test
187
188    unstripped_cc_rule(
189        name = unstripped_name,
190        deps = [root_name, sanitizer_deps_name] + deps + system_static_deps + stl_info.static_deps,
191        dynamic_deps = binary_dynamic_deps,
192        features = toolchain_features,
193        linkopts = linkopts,
194        additional_linker_inputs = additional_linker_inputs,
195        target_compatible_with = target_compatible_with,
196        tags = ["manual"],
197        **kwargs
198    )
199
200    versioned_name = name + "_versioned"
201    versioned_binary(
202        name = versioned_name,
203        src = unstripped_name,
204        stamp_build_number = use_version_lib,
205        tags = ["manual"],
206        testonly = generate_cc_test,
207        # Potentially have internal cc_test dependency so keep
208        # --trim_test_configuration optimization working. See b/288969037 for more info
209        transitive_configs = ["//command_line_option/fragment:test"] if generate_cc_test else [],
210    )
211
212    stripped_cc_rule(
213        name = name,
214        stem = stem,
215        suffix = suffix,
216        src = versioned_name,
217        runtime_deps = runtime_deps,
218        target_compatible_with = target_compatible_with,
219        tags = tags,
220        unstripped = unstripped_name,
221        features = toolchain_features,
222        testonly = generate_cc_test,
223        androidmk_deps = [root_name],
224        linkopts = linkopts,
225        package_name = native.package_name(),
226        **strip
227    )
228