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