xref: /aosp_15_r20/build/bazel/rules/cc/cc_library_common.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project
2*7594170eSAndroid Build Coastguard Worker#
3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*7594170eSAndroid Build Coastguard Worker#
7*7594170eSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*7594170eSAndroid Build Coastguard Worker#
9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*7594170eSAndroid Build Coastguard Worker# limitations under the License.
14*7594170eSAndroid Build Coastguard Worker
15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths")
16*7594170eSAndroid Build Coastguard Workerload("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
17*7594170eSAndroid Build Coastguard Workerload("@soong_injection//android:constants.bzl", android_constants = "constants")
18*7594170eSAndroid Build Coastguard Workerload("@soong_injection//api_levels:platform_versions.bzl", "platform_versions")
19*7594170eSAndroid Build Coastguard Workerload("@soong_injection//cc_toolchain:config_constants.bzl", cc_constants = "constants")
20*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:common.bzl", "strip_bp2build_label_suffix")
21*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/common:api.bzl", "api")
22*7594170eSAndroid Build Coastguard Worker
23*7594170eSAndroid Build Coastguard Worker_static_bionic_targets = ["//bionic/libc:libc_bp2build_cc_library_static", "//bionic/libdl:libdl_bp2build_cc_library_static", "//bionic/libm:libm_bp2build_cc_library_static"]
24*7594170eSAndroid Build Coastguard Worker
25*7594170eSAndroid Build Coastguard Worker# When building a APEX, stub libraries of libc, libdl, libm should be used in linking.
26*7594170eSAndroid Build Coastguard Worker_bionic_stub_targets = [
27*7594170eSAndroid Build Coastguard Worker    "//bionic/libc:libc_stub_libs_current",
28*7594170eSAndroid Build Coastguard Worker    "//bionic/libdl:libdl_stub_libs_current",
29*7594170eSAndroid Build Coastguard Worker    "//bionic/libm:libm_stub_libs_current",
30*7594170eSAndroid Build Coastguard Worker]
31*7594170eSAndroid Build Coastguard Worker
32*7594170eSAndroid Build Coastguard Worker# When building an android_app/android_test that set an sdk_version, NDK variant of stub libraries of libc, libdl, libm should be used in linking.
33*7594170eSAndroid Build Coastguard Worker_bionic_ndk_stub_targets = [
34*7594170eSAndroid Build Coastguard Worker    "//bionic/libc:libc.ndk_stub_libs_current",
35*7594170eSAndroid Build Coastguard Worker    "//bionic/libdl:libdl.ndk_stub_libs_current",
36*7594170eSAndroid Build Coastguard Worker    "//bionic/libm:libm.ndk_stub_libs_current",
37*7594170eSAndroid Build Coastguard Worker]
38*7594170eSAndroid Build Coastguard Worker
39*7594170eSAndroid Build Coastguard Worker# The default system_dynamic_deps value for cc libraries. This value should be
40*7594170eSAndroid Build Coastguard Worker# used if no value for system_dynamic_deps is specified.
41*7594170eSAndroid Build Coastguard Workersystem_dynamic_deps_defaults = select({
42*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:android-in_apex": _bionic_stub_targets,
43*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:android-non_apex": _bionic_stub_targets,
44*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:linux_bionic-in_apex": _bionic_stub_targets,
45*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:linux_bionic-non_apex": _bionic_stub_targets,
46*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:unbundled_app": _bionic_ndk_stub_targets,
47*7594170eSAndroid Build Coastguard Worker    "//conditions:default": [],
48*7594170eSAndroid Build Coastguard Worker})
49*7594170eSAndroid Build Coastguard Worker
50*7594170eSAndroid Build Coastguard Workersystem_static_deps_defaults = select({
51*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:android-in_apex": _bionic_stub_targets,
52*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:android-non_apex": _static_bionic_targets,
53*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:linux_bionic-in_apex": _bionic_stub_targets,
54*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:linux_bionic-non_apex": _static_bionic_targets,
55*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/apex:unbundled_app": _bionic_ndk_stub_targets,
56*7594170eSAndroid Build Coastguard Worker    "//conditions:default": [],
57*7594170eSAndroid Build Coastguard Worker})
58*7594170eSAndroid Build Coastguard Worker
59*7594170eSAndroid Build Coastguard Worker# List comes from here:
60*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/cc.go;l=1441;drc=9fd9129b5728602a4768e8e8e695660b683c405e
61*7594170eSAndroid Build Coastguard Worker_bionic_libs = ["libc", "libm", "libdl", "libdl_android", "linker", "linkerconfig"]
62*7594170eSAndroid Build Coastguard Worker
63*7594170eSAndroid Build Coastguard Worker# Comes from here:
64*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/cc.go;l=1450;drc=9fd9129b5728602a4768e8e8e695660b683c405e
65*7594170eSAndroid Build Coastguard Worker_bootstrap_libs = ["libclang_rt.hwasan"]
66*7594170eSAndroid Build Coastguard Worker
67*7594170eSAndroid Build Coastguard Workerfuture_version = 10000
68*7594170eSAndroid Build Coastguard Worker
69*7594170eSAndroid Build Coastguard WorkerCcSanitizerLibraryInfo = provider(
70*7594170eSAndroid Build Coastguard Worker    "Denotes which sanitizer libraries to include",
71*7594170eSAndroid Build Coastguard Worker    fields = {
72*7594170eSAndroid Build Coastguard Worker        "propagate_ubsan_deps": ("True if any ubsan sanitizers are " +
73*7594170eSAndroid Build Coastguard Worker                                 "enabled on any transitive deps, or " +
74*7594170eSAndroid Build Coastguard Worker                                 "the current target. False otherwise"),
75*7594170eSAndroid Build Coastguard Worker    },
76*7594170eSAndroid Build Coastguard Worker)
77*7594170eSAndroid Build Coastguard Worker
78*7594170eSAndroid Build Coastguard Worker# Must be called from within a rule (not a macro) so that the features select
79*7594170eSAndroid Build Coastguard Worker# has been resolved.
80*7594170eSAndroid Build Coastguard Workerdef get_sanitizer_lib_info(features, deps):
81*7594170eSAndroid Build Coastguard Worker    propagate_ubsan_deps = False
82*7594170eSAndroid Build Coastguard Worker    for feature in features:
83*7594170eSAndroid Build Coastguard Worker        if feature.startswith("ubsan_"):
84*7594170eSAndroid Build Coastguard Worker            propagate_ubsan_deps = True
85*7594170eSAndroid Build Coastguard Worker            break
86*7594170eSAndroid Build Coastguard Worker    if not propagate_ubsan_deps:
87*7594170eSAndroid Build Coastguard Worker        for dep in deps:
88*7594170eSAndroid Build Coastguard Worker            if (CcSanitizerLibraryInfo in dep and
89*7594170eSAndroid Build Coastguard Worker                dep[CcSanitizerLibraryInfo].propagate_ubsan_deps):
90*7594170eSAndroid Build Coastguard Worker                propagate_ubsan_deps = True
91*7594170eSAndroid Build Coastguard Worker                break
92*7594170eSAndroid Build Coastguard Worker    return CcSanitizerLibraryInfo(
93*7594170eSAndroid Build Coastguard Worker        propagate_ubsan_deps = propagate_ubsan_deps,
94*7594170eSAndroid Build Coastguard Worker    )
95*7594170eSAndroid Build Coastguard Worker
96*7594170eSAndroid Build Coastguard Workerdef _sanitizer_deps_impl(ctx):
97*7594170eSAndroid Build Coastguard Worker    if (CcSanitizerLibraryInfo in ctx.attr.dep and
98*7594170eSAndroid Build Coastguard Worker        ctx.attr.dep[CcSanitizerLibraryInfo].propagate_ubsan_deps):
99*7594170eSAndroid Build Coastguard Worker        # To operate correctly with native cc_binary and cc_sharedLibrary,
100*7594170eSAndroid Build Coastguard Worker        # copy the linker inputs and ensure that this target is marked as the
101*7594170eSAndroid Build Coastguard Worker        # "owner". Otherwise, upstream targets may drop these linker inputs.
102*7594170eSAndroid Build Coastguard Worker        # See b/264894507.
103*7594170eSAndroid Build Coastguard Worker        libraries = [
104*7594170eSAndroid Build Coastguard Worker            lib
105*7594170eSAndroid Build Coastguard Worker            for input in ctx.attr._ubsan_library[CcInfo].linking_context.linker_inputs.to_list()
106*7594170eSAndroid Build Coastguard Worker            for lib in input.libraries
107*7594170eSAndroid Build Coastguard Worker        ]
108*7594170eSAndroid Build Coastguard Worker        new_linker_input = cc_common.create_linker_input(
109*7594170eSAndroid Build Coastguard Worker            owner = ctx.label,
110*7594170eSAndroid Build Coastguard Worker            libraries = depset(direct = libraries),
111*7594170eSAndroid Build Coastguard Worker        )
112*7594170eSAndroid Build Coastguard Worker        linking_context = cc_common.create_linking_context(
113*7594170eSAndroid Build Coastguard Worker            linker_inputs = depset(direct = [new_linker_input]),
114*7594170eSAndroid Build Coastguard Worker        )
115*7594170eSAndroid Build Coastguard Worker        return [CcInfo(linking_context = linking_context)]
116*7594170eSAndroid Build Coastguard Worker    return [CcInfo()]
117*7594170eSAndroid Build Coastguard Worker
118*7594170eSAndroid Build Coastguard Worker# This rule is essentially a workaround to be able to add dependencies
119*7594170eSAndroid Build Coastguard Worker# conditionally based on provider values
120*7594170eSAndroid Build Coastguard Workersanitizer_deps = rule(
121*7594170eSAndroid Build Coastguard Worker    implementation = _sanitizer_deps_impl,
122*7594170eSAndroid Build Coastguard Worker    doc = "A rule that propagates given sanitizer dependencies if the " +
123*7594170eSAndroid Build Coastguard Worker          "proper conditions are met",
124*7594170eSAndroid Build Coastguard Worker    attrs = {
125*7594170eSAndroid Build Coastguard Worker        "dep": attr.label(
126*7594170eSAndroid Build Coastguard Worker            mandatory = True,
127*7594170eSAndroid Build Coastguard Worker            doc = "library to check for sanitizer dependency propagation",
128*7594170eSAndroid Build Coastguard Worker        ),
129*7594170eSAndroid Build Coastguard Worker        "_ubsan_library": attr.label(
130*7594170eSAndroid Build Coastguard Worker            default = "//prebuilts/clang/host/linux-x86:libclang_rt.ubsan_minimal",
131*7594170eSAndroid Build Coastguard Worker            doc = "The library target corresponding to the undefined " +
132*7594170eSAndroid Build Coastguard Worker                  "behavior sanitizer library to be used",
133*7594170eSAndroid Build Coastguard Worker        ),
134*7594170eSAndroid Build Coastguard Worker    },
135*7594170eSAndroid Build Coastguard Worker    provides = [CcInfo],
136*7594170eSAndroid Build Coastguard Worker)
137*7594170eSAndroid Build Coastguard Worker
138*7594170eSAndroid Build Coastguard Workerdef sdk_version_feature_from_parsed_version(version):
139*7594170eSAndroid Build Coastguard Worker    return "sdk_version_" + str(version)
140*7594170eSAndroid Build Coastguard Worker
141*7594170eSAndroid Build Coastguard Workerdef _create_sdk_version_features_map():
142*7594170eSAndroid Build Coastguard Worker    version_feature_map = {}
143*7594170eSAndroid Build Coastguard Worker    for level in api.api_levels.values():
144*7594170eSAndroid Build Coastguard Worker        version_feature_map["//build/bazel/rules/apex:min_sdk_version_" + str(level)] = [sdk_version_feature_from_parsed_version(level)]
145*7594170eSAndroid Build Coastguard Worker    version_feature_map["//conditions:default"] = [sdk_version_feature_from_parsed_version(future_version)]
146*7594170eSAndroid Build Coastguard Worker
147*7594170eSAndroid Build Coastguard Worker    return version_feature_map
148*7594170eSAndroid Build Coastguard Worker
149*7594170eSAndroid Build Coastguard Workersdk_version_features = select(_create_sdk_version_features_map())
150*7594170eSAndroid Build Coastguard Worker
151*7594170eSAndroid Build Coastguard Workerdef add_lists_defaulting_to_none(*args):
152*7594170eSAndroid Build Coastguard Worker    """Adds multiple lists, but is well behaved with a `None` default."""
153*7594170eSAndroid Build Coastguard Worker    combined = None
154*7594170eSAndroid Build Coastguard Worker    for arg in args:
155*7594170eSAndroid Build Coastguard Worker        if arg != None:
156*7594170eSAndroid Build Coastguard Worker            if combined == None:
157*7594170eSAndroid Build Coastguard Worker                combined = []
158*7594170eSAndroid Build Coastguard Worker            combined += arg
159*7594170eSAndroid Build Coastguard Worker
160*7594170eSAndroid Build Coastguard Worker    return combined
161*7594170eSAndroid Build Coastguard Worker
162*7594170eSAndroid Build Coastguard Worker# get_includes_paths expects a rule context, a list of directories, and
163*7594170eSAndroid Build Coastguard Worker# whether the directories are package-relative and returns a list of exec
164*7594170eSAndroid Build Coastguard Worker# root-relative paths. This handles the need to search for files both in the
165*7594170eSAndroid Build Coastguard Worker# source tree and generated files.
166*7594170eSAndroid Build Coastguard Workerdef get_includes_paths(ctx, dirs, package_relative = True):
167*7594170eSAndroid Build Coastguard Worker    execution_relative_dirs = []
168*7594170eSAndroid Build Coastguard Worker    for rel_dir in dirs:
169*7594170eSAndroid Build Coastguard Worker        if rel_dir == ".":
170*7594170eSAndroid Build Coastguard Worker            rel_dir = ""
171*7594170eSAndroid Build Coastguard Worker        execution_rel_dir = rel_dir
172*7594170eSAndroid Build Coastguard Worker        if package_relative:
173*7594170eSAndroid Build Coastguard Worker            execution_rel_dir = ctx.label.package
174*7594170eSAndroid Build Coastguard Worker            if len(rel_dir) > 0:
175*7594170eSAndroid Build Coastguard Worker                execution_rel_dir = execution_rel_dir + "/" + rel_dir
176*7594170eSAndroid Build Coastguard Worker
177*7594170eSAndroid Build Coastguard Worker        # To allow this repo to be used as an external one.
178*7594170eSAndroid Build Coastguard Worker        repo_prefix_dir = execution_rel_dir
179*7594170eSAndroid Build Coastguard Worker        if ctx.label.workspace_root != "":
180*7594170eSAndroid Build Coastguard Worker            repo_prefix_dir = ctx.label.workspace_root + "/" + execution_rel_dir
181*7594170eSAndroid Build Coastguard Worker        execution_relative_dirs.append(repo_prefix_dir)
182*7594170eSAndroid Build Coastguard Worker
183*7594170eSAndroid Build Coastguard Worker        # to support generated files, we also need to export includes relatives to the bin directory
184*7594170eSAndroid Build Coastguard Worker        if not execution_rel_dir.startswith("/"):
185*7594170eSAndroid Build Coastguard Worker            execution_relative_dirs.append(ctx.bin_dir.path + "/" + execution_rel_dir)
186*7594170eSAndroid Build Coastguard Worker    return execution_relative_dirs
187*7594170eSAndroid Build Coastguard Worker
188*7594170eSAndroid Build Coastguard Workerdef create_ccinfo_for_includes(
189*7594170eSAndroid Build Coastguard Worker        ctx,
190*7594170eSAndroid Build Coastguard Worker        hdrs = [],
191*7594170eSAndroid Build Coastguard Worker        includes = [],
192*7594170eSAndroid Build Coastguard Worker        absolute_includes = [],
193*7594170eSAndroid Build Coastguard Worker        system_includes = [],
194*7594170eSAndroid Build Coastguard Worker        deps = []):
195*7594170eSAndroid Build Coastguard Worker    # Create a compilation context using the string includes of this target.
196*7594170eSAndroid Build Coastguard Worker    compilation_context = cc_common.create_compilation_context(
197*7594170eSAndroid Build Coastguard Worker        headers = depset(hdrs),
198*7594170eSAndroid Build Coastguard Worker        includes = depset(
199*7594170eSAndroid Build Coastguard Worker            get_includes_paths(ctx, includes) +
200*7594170eSAndroid Build Coastguard Worker            get_includes_paths(ctx, absolute_includes, package_relative = False),
201*7594170eSAndroid Build Coastguard Worker        ),
202*7594170eSAndroid Build Coastguard Worker        system_includes = depset(get_includes_paths(ctx, system_includes)),
203*7594170eSAndroid Build Coastguard Worker    )
204*7594170eSAndroid Build Coastguard Worker
205*7594170eSAndroid Build Coastguard Worker    # Combine this target's compilation context with those of the deps; use only
206*7594170eSAndroid Build Coastguard Worker    # the compilation context of the combined CcInfo.
207*7594170eSAndroid Build Coastguard Worker    cc_infos = [dep[CcInfo] for dep in deps]
208*7594170eSAndroid Build Coastguard Worker    cc_infos.append(CcInfo(compilation_context = compilation_context))
209*7594170eSAndroid Build Coastguard Worker    combined_info = cc_common.merge_cc_infos(cc_infos = cc_infos)
210*7594170eSAndroid Build Coastguard Worker
211*7594170eSAndroid Build Coastguard Worker    return CcInfo(compilation_context = combined_info.compilation_context)
212*7594170eSAndroid Build Coastguard Worker
213*7594170eSAndroid Build Coastguard Workerdef is_external_directory(package_name):
214*7594170eSAndroid Build Coastguard Worker    if package_name.startswith("external"):
215*7594170eSAndroid Build Coastguard Worker        return True
216*7594170eSAndroid Build Coastguard Worker    if package_name.startswith("hardware"):
217*7594170eSAndroid Build Coastguard Worker        paths = package_name.split("/")
218*7594170eSAndroid Build Coastguard Worker        if len(paths) < 2:
219*7594170eSAndroid Build Coastguard Worker            return True
220*7594170eSAndroid Build Coastguard Worker        secondary_path = paths[1]
221*7594170eSAndroid Build Coastguard Worker        if secondary_path in ["google", "interfaces", "ril"]:
222*7594170eSAndroid Build Coastguard Worker            return False
223*7594170eSAndroid Build Coastguard Worker        return not secondary_path.startswith("libhardware")
224*7594170eSAndroid Build Coastguard Worker    if package_name.startswith("vendor"):
225*7594170eSAndroid Build Coastguard Worker        paths = package_name.split("/")
226*7594170eSAndroid Build Coastguard Worker        if len(paths) < 2:
227*7594170eSAndroid Build Coastguard Worker            return True
228*7594170eSAndroid Build Coastguard Worker        secondary_path = paths[1]
229*7594170eSAndroid Build Coastguard Worker        return "google" not in secondary_path
230*7594170eSAndroid Build Coastguard Worker    return False
231*7594170eSAndroid Build Coastguard Worker
232*7594170eSAndroid Build Coastguard Worker# TODO: Move this to a common rule dir, instead of a cc rule dir. Nothing here
233*7594170eSAndroid Build Coastguard Worker# should be cc specific, except that the current callers are (only) cc rules.
234*7594170eSAndroid Build Coastguard Workerdef parse_sdk_version(version):
235*7594170eSAndroid Build Coastguard Worker    if version == "apex_inherit":
236*7594170eSAndroid Build Coastguard Worker        # use the version determined by the transition value.
237*7594170eSAndroid Build Coastguard Worker        return sdk_version_features + [sdk_version_feature_from_parsed_version("apex_inherit")]
238*7594170eSAndroid Build Coastguard Worker
239*7594170eSAndroid Build Coastguard Worker    return [sdk_version_feature_from_parsed_version(parse_apex_sdk_version(version))]
240*7594170eSAndroid Build Coastguard Worker
241*7594170eSAndroid Build Coastguard Workerdef parse_apex_sdk_version(version):
242*7594170eSAndroid Build Coastguard Worker    if version == "" or version == "current" or version == "10000":
243*7594170eSAndroid Build Coastguard Worker        return future_version
244*7594170eSAndroid Build Coastguard Worker    elif version in api.api_levels.keys():
245*7594170eSAndroid Build Coastguard Worker        return api.api_levels[version]
246*7594170eSAndroid Build Coastguard Worker    elif version.isdigit():
247*7594170eSAndroid Build Coastguard Worker        version = int(version)
248*7594170eSAndroid Build Coastguard Worker        if version in api.api_levels.values():
249*7594170eSAndroid Build Coastguard Worker            return version
250*7594170eSAndroid Build Coastguard Worker        elif version == platform_versions.platform_sdk_version:
251*7594170eSAndroid Build Coastguard Worker            # For internal branch states, support parsing a finalized version number
252*7594170eSAndroid Build Coastguard Worker            # that's also still in
253*7594170eSAndroid Build Coastguard Worker            # platform_versions.platform_version_active_codenames, but not api.api_levels.
254*7594170eSAndroid Build Coastguard Worker            #
255*7594170eSAndroid Build Coastguard Worker            # This happens a few months each year on internal branches where the
256*7594170eSAndroid Build Coastguard Worker            # internal master branch has a finalized API, but is not released yet,
257*7594170eSAndroid Build Coastguard Worker            # therefore the Platform_sdk_version is usually latest AOSP dessert
258*7594170eSAndroid Build Coastguard Worker            # version + 1. The generated api.api_levels map sets these to 9000 + i,
259*7594170eSAndroid Build Coastguard Worker            # where i is the index of the current/future version, so version is not
260*7594170eSAndroid Build Coastguard Worker            # in the api.api_levels.values() list, but it is a valid sdk version.
261*7594170eSAndroid Build Coastguard Worker            #
262*7594170eSAndroid Build Coastguard Worker            # See also b/234321488#comment2
263*7594170eSAndroid Build Coastguard Worker            return version
264*7594170eSAndroid Build Coastguard Worker    fail("Unknown sdk version: %s, could not be parsed as " % version +
265*7594170eSAndroid Build Coastguard Worker         "an integer and/or is not a recognized codename. Valid api levels are:" +
266*7594170eSAndroid Build Coastguard Worker         str(api.api_levels))
267*7594170eSAndroid Build Coastguard Worker
268*7594170eSAndroid Build Coastguard WorkerCPP_EXTENSIONS = ["cc", "cpp", "c++"]
269*7594170eSAndroid Build Coastguard Worker
270*7594170eSAndroid Build Coastguard WorkerC_EXTENSIONS = ["c"]
271*7594170eSAndroid Build Coastguard Worker
272*7594170eSAndroid Build Coastguard Worker_HEADER_EXTENSIONS = ["h", "hh", "hpp", "hxx", "h++", "inl", "inc", "ipp", "h.generic"]
273*7594170eSAndroid Build Coastguard Worker
274*7594170eSAndroid Build Coastguard Workerdef get_non_header_srcs(input_srcs, exclude_srcs = [], source_extensions = None, header_extensions = _HEADER_EXTENSIONS):
275*7594170eSAndroid Build Coastguard Worker    """get_non_header_srcs returns a list of srcs that do not have header extensions and aren't in the exclude srcs list
276*7594170eSAndroid Build Coastguard Worker
277*7594170eSAndroid Build Coastguard Worker    Args:
278*7594170eSAndroid Build Coastguard Worker        input_srcs (list[File]): list of files to filter
279*7594170eSAndroid Build Coastguard Worker        exclude_srcs (list[File]): list of files that should be excluded from the returned list
280*7594170eSAndroid Build Coastguard Worker        source_extensions (list[str]): list of extensions that designate sources.
281*7594170eSAndroid Build Coastguard Worker            If None, all extensions are valid. Otherwise only source with these extensions are returned
282*7594170eSAndroid Build Coastguard Worker        header_extensions (list[str]): list of extensions that designate headers
283*7594170eSAndroid Build Coastguard Worker    Returns:
284*7594170eSAndroid Build Coastguard Worker        srcs, hdrs (list[File], list[File]): tuple of lists of files; srcs have non-header extension and are not excluded,
285*7594170eSAndroid Build Coastguard Worker            and hdrs are files with header extensions
286*7594170eSAndroid Build Coastguard Worker    """
287*7594170eSAndroid Build Coastguard Worker    srcs = []
288*7594170eSAndroid Build Coastguard Worker    hdrs = []
289*7594170eSAndroid Build Coastguard Worker    for s in input_srcs:
290*7594170eSAndroid Build Coastguard Worker        is_source = not source_extensions or s.extension in source_extensions
291*7594170eSAndroid Build Coastguard Worker        if s.extension in header_extensions:
292*7594170eSAndroid Build Coastguard Worker            hdrs.append(s)
293*7594170eSAndroid Build Coastguard Worker        elif is_source and s not in exclude_srcs:
294*7594170eSAndroid Build Coastguard Worker            srcs.append(s)
295*7594170eSAndroid Build Coastguard Worker    return srcs, hdrs
296*7594170eSAndroid Build Coastguard Worker
297*7594170eSAndroid Build Coastguard Workerdef prefix_in_list(str, prefixes):
298*7594170eSAndroid Build Coastguard Worker    """returns the prefix if any element of prefixes is a prefix of path
299*7594170eSAndroid Build Coastguard Worker
300*7594170eSAndroid Build Coastguard Worker    Args:
301*7594170eSAndroid Build Coastguard Worker        str (str): the string to compare prefixes against
302*7594170eSAndroid Build Coastguard Worker        prefixes (list[str]): a list of prefixes to check against str
303*7594170eSAndroid Build Coastguard Worker    Returns:
304*7594170eSAndroid Build Coastguard Worker        prefix (str or None): the prefix (if any) that str starts with
305*7594170eSAndroid Build Coastguard Worker    """
306*7594170eSAndroid Build Coastguard Worker    for prefix in prefixes:
307*7594170eSAndroid Build Coastguard Worker        if str.startswith(prefix):
308*7594170eSAndroid Build Coastguard Worker            return prefix
309*7594170eSAndroid Build Coastguard Worker    return None
310*7594170eSAndroid Build Coastguard Worker
311*7594170eSAndroid Build Coastguard Worker_DISALLOWED_INCLUDE_DIRS = android_constants.NeverAllowNotInIncludeDir
312*7594170eSAndroid Build Coastguard Worker_PACKAGES_DISALLOWED_TO_SPECIFY_INCLUDE_DIRS = android_constants.NeverAllowNoUseIncludeDir
313*7594170eSAndroid Build Coastguard Worker
314*7594170eSAndroid Build Coastguard Workerdef check_absolute_include_dirs_disabled(target_package, absolute_includes):
315*7594170eSAndroid Build Coastguard Worker    """checks that absolute include dirs are disabled for some directories
316*7594170eSAndroid Build Coastguard Worker
317*7594170eSAndroid Build Coastguard Worker    Args:
318*7594170eSAndroid Build Coastguard Worker        target_package (str): package of current target
319*7594170eSAndroid Build Coastguard Worker        absolute_includes (list[str]): list of absolute include directories
320*7594170eSAndroid Build Coastguard Worker    """
321*7594170eSAndroid Build Coastguard Worker    if len(absolute_includes) > 0:
322*7594170eSAndroid Build Coastguard Worker        disallowed_prefix = prefix_in_list(
323*7594170eSAndroid Build Coastguard Worker            target_package,
324*7594170eSAndroid Build Coastguard Worker            _PACKAGES_DISALLOWED_TO_SPECIFY_INCLUDE_DIRS,
325*7594170eSAndroid Build Coastguard Worker        )
326*7594170eSAndroid Build Coastguard Worker        if disallowed_prefix != None:
327*7594170eSAndroid Build Coastguard Worker            fail("include_dirs is deprecated, all usages of them in '" +
328*7594170eSAndroid Build Coastguard Worker                 disallowed_prefix + "' have been migrated to use alternate" +
329*7594170eSAndroid Build Coastguard Worker                 " mechanisms and so can no longer be used.")
330*7594170eSAndroid Build Coastguard Worker
331*7594170eSAndroid Build Coastguard Worker    for path in absolute_includes:
332*7594170eSAndroid Build Coastguard Worker        if path in _DISALLOWED_INCLUDE_DIRS:
333*7594170eSAndroid Build Coastguard Worker            fail("include_dirs is deprecated, all usages of '" + path + "' have" +
334*7594170eSAndroid Build Coastguard Worker                 " been migrated to use alternate mechanisms and so can no longer" +
335*7594170eSAndroid Build Coastguard Worker                 " be used.")
336*7594170eSAndroid Build Coastguard Worker
337*7594170eSAndroid Build Coastguard Workerdef get_compilation_args(toolchain, feature_config, flags, compilation_ctx, action_name):
338*7594170eSAndroid Build Coastguard Worker    compilation_vars = cc_common.create_compile_variables(
339*7594170eSAndroid Build Coastguard Worker        cc_toolchain = toolchain,
340*7594170eSAndroid Build Coastguard Worker        feature_configuration = feature_config,
341*7594170eSAndroid Build Coastguard Worker        user_compile_flags = flags,
342*7594170eSAndroid Build Coastguard Worker        include_directories = compilation_ctx.includes,
343*7594170eSAndroid Build Coastguard Worker        quote_include_directories = compilation_ctx.quote_includes,
344*7594170eSAndroid Build Coastguard Worker        system_include_directories = compilation_ctx.system_includes,
345*7594170eSAndroid Build Coastguard Worker        framework_include_directories = compilation_ctx.framework_includes,
346*7594170eSAndroid Build Coastguard Worker    )
347*7594170eSAndroid Build Coastguard Worker
348*7594170eSAndroid Build Coastguard Worker    return cc_common.get_memory_inefficient_command_line(
349*7594170eSAndroid Build Coastguard Worker        feature_configuration = feature_config,
350*7594170eSAndroid Build Coastguard Worker        action_name = action_name,
351*7594170eSAndroid Build Coastguard Worker        variables = compilation_vars,
352*7594170eSAndroid Build Coastguard Worker    )
353*7594170eSAndroid Build Coastguard Worker
354*7594170eSAndroid Build Coastguard Workerdef build_compilation_flags(ctx, deps, user_flags, action_name):
355*7594170eSAndroid Build Coastguard Worker    cc_toolchain = find_cpp_toolchain(ctx)
356*7594170eSAndroid Build Coastguard Worker
357*7594170eSAndroid Build Coastguard Worker    feature_config = cc_common.configure_features(
358*7594170eSAndroid Build Coastguard Worker        ctx = ctx,
359*7594170eSAndroid Build Coastguard Worker        cc_toolchain = cc_toolchain,
360*7594170eSAndroid Build Coastguard Worker        language = "c++",
361*7594170eSAndroid Build Coastguard Worker        requested_features = ctx.features,
362*7594170eSAndroid Build Coastguard Worker        unsupported_features = ctx.disabled_features,
363*7594170eSAndroid Build Coastguard Worker    )
364*7594170eSAndroid Build Coastguard Worker
365*7594170eSAndroid Build Coastguard Worker    cc_info = cc_common.merge_cc_infos(direct_cc_infos = [d[CcInfo] for d in deps])
366*7594170eSAndroid Build Coastguard Worker
367*7594170eSAndroid Build Coastguard Worker    compilation_flags = get_compilation_args(
368*7594170eSAndroid Build Coastguard Worker        toolchain = cc_toolchain,
369*7594170eSAndroid Build Coastguard Worker        feature_config = feature_config,
370*7594170eSAndroid Build Coastguard Worker        flags = user_flags,
371*7594170eSAndroid Build Coastguard Worker        compilation_ctx = cc_info.compilation_context,
372*7594170eSAndroid Build Coastguard Worker        action_name = action_name,
373*7594170eSAndroid Build Coastguard Worker    )
374*7594170eSAndroid Build Coastguard Worker
375*7594170eSAndroid Build Coastguard Worker    return cc_info.compilation_context, compilation_flags
376*7594170eSAndroid Build Coastguard Worker
377*7594170eSAndroid Build Coastguard Workerdef is_bionic_lib(name):
378*7594170eSAndroid Build Coastguard Worker    return name in _bionic_libs
379*7594170eSAndroid Build Coastguard Worker
380*7594170eSAndroid Build Coastguard Workerdef is_bootstrap_lib(name):
381*7594170eSAndroid Build Coastguard Worker    return name in _bootstrap_libs
382*7594170eSAndroid Build Coastguard Worker
383*7594170eSAndroid Build Coastguard WorkerCcAndroidMkInfo = provider(
384*7594170eSAndroid Build Coastguard Worker    "Provides information to be passed to AndroidMk in Soong",
385*7594170eSAndroid Build Coastguard Worker    fields = {
386*7594170eSAndroid Build Coastguard Worker        "local_static_libs": "list of target names passed to LOCAL_STATIC_LIBRARIES AndroidMk variable",
387*7594170eSAndroid Build Coastguard Worker        "local_whole_static_libs": "list of target names passed to LOCAL_WHOLE_STATIC_LIBRARIES AndroidMk variable",
388*7594170eSAndroid Build Coastguard Worker        "local_shared_libs": "list of target names passed to LOCAL_SHARED_LIBRARIES AndroidMk variable",
389*7594170eSAndroid Build Coastguard Worker    },
390*7594170eSAndroid Build Coastguard Worker)
391*7594170eSAndroid Build Coastguard Worker
392*7594170eSAndroid Build Coastguard Workerdef create_cc_androidmk_provider(*, static_deps, whole_archive_deps, dynamic_deps):
393*7594170eSAndroid Build Coastguard Worker    # Since this information is provided to Soong for mixed builds,
394*7594170eSAndroid Build Coastguard Worker    # we are just taking the Soong module name rather than the Bazel
395*7594170eSAndroid Build Coastguard Worker    # label.
396*7594170eSAndroid Build Coastguard Worker    # TODO(b/266197834) consider moving this logic to the mixed builds
397*7594170eSAndroid Build Coastguard Worker    # handler in Soong
398*7594170eSAndroid Build Coastguard Worker    local_static_libs = [
399*7594170eSAndroid Build Coastguard Worker        strip_bp2build_label_suffix(d.label.name)
400*7594170eSAndroid Build Coastguard Worker        for d in static_deps
401*7594170eSAndroid Build Coastguard Worker    ]
402*7594170eSAndroid Build Coastguard Worker    local_whole_static_libs = [
403*7594170eSAndroid Build Coastguard Worker        strip_bp2build_label_suffix(d.label.name)
404*7594170eSAndroid Build Coastguard Worker        for d in whole_archive_deps
405*7594170eSAndroid Build Coastguard Worker    ]
406*7594170eSAndroid Build Coastguard Worker    local_shared_libs = [
407*7594170eSAndroid Build Coastguard Worker        strip_bp2build_label_suffix(d.label.name)
408*7594170eSAndroid Build Coastguard Worker        for d in dynamic_deps
409*7594170eSAndroid Build Coastguard Worker    ]
410*7594170eSAndroid Build Coastguard Worker    return CcAndroidMkInfo(
411*7594170eSAndroid Build Coastguard Worker        local_static_libs = local_static_libs,
412*7594170eSAndroid Build Coastguard Worker        local_whole_static_libs = local_whole_static_libs,
413*7594170eSAndroid Build Coastguard Worker        local_shared_libs = local_shared_libs,
414*7594170eSAndroid Build Coastguard Worker    )
415*7594170eSAndroid Build Coastguard Worker
416*7594170eSAndroid Build Coastguard Workerdef create_cc_prebuilt_library_info(ctx, lib_to_link):
417*7594170eSAndroid Build Coastguard Worker    "Create the CcInfo for a prebuilt_library_{shared,static}"
418*7594170eSAndroid Build Coastguard Worker
419*7594170eSAndroid Build Coastguard Worker    compilation_context = cc_common.create_compilation_context(
420*7594170eSAndroid Build Coastguard Worker        includes = depset(get_includes_paths(ctx, ctx.attr.export_includes)),
421*7594170eSAndroid Build Coastguard Worker        system_includes = depset(get_includes_paths(ctx, ctx.attr.export_system_includes)),
422*7594170eSAndroid Build Coastguard Worker    )
423*7594170eSAndroid Build Coastguard Worker    linker_input = cc_common.create_linker_input(
424*7594170eSAndroid Build Coastguard Worker        owner = ctx.label,
425*7594170eSAndroid Build Coastguard Worker        libraries = depset(direct = [lib_to_link] if lib_to_link != None else []),
426*7594170eSAndroid Build Coastguard Worker    )
427*7594170eSAndroid Build Coastguard Worker    linking_context = cc_common.create_linking_context(
428*7594170eSAndroid Build Coastguard Worker        linker_inputs = depset(direct = [linker_input]),
429*7594170eSAndroid Build Coastguard Worker    )
430*7594170eSAndroid Build Coastguard Worker    return [
431*7594170eSAndroid Build Coastguard Worker        CcInfo(
432*7594170eSAndroid Build Coastguard Worker            compilation_context = compilation_context,
433*7594170eSAndroid Build Coastguard Worker            linking_context = linking_context,
434*7594170eSAndroid Build Coastguard Worker        ),
435*7594170eSAndroid Build Coastguard Worker        linker_input,
436*7594170eSAndroid Build Coastguard Worker    ]
437*7594170eSAndroid Build Coastguard Worker
438*7594170eSAndroid Build Coastguard Worker# Check that -l<lib> requested via linkopts is supported by the toolchain.
439*7594170eSAndroid Build Coastguard Workerdef check_valid_ldlibs(ctx, linkopts):
440*7594170eSAndroid Build Coastguard Worker    libs_in_linkopts = [lo for lo in linkopts if lo.startswith("-l")]
441*7594170eSAndroid Build Coastguard Worker    if not libs_in_linkopts:
442*7594170eSAndroid Build Coastguard Worker        return
443*7594170eSAndroid Build Coastguard Worker
444*7594170eSAndroid Build Coastguard Worker    # Android
445*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._android_constraint[platform_common.ConstraintValueInfo]):
446*7594170eSAndroid Build Coastguard Worker        fail("Library requested via -l is not supported for device builds. Use implementation_deps instead.")
447*7594170eSAndroid Build Coastguard Worker
448*7594170eSAndroid Build Coastguard Worker    libs_available = []
449*7594170eSAndroid Build Coastguard Worker
450*7594170eSAndroid Build Coastguard Worker    # linux
451*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._linux_constraint[platform_common.ConstraintValueInfo]):
452*7594170eSAndroid Build Coastguard Worker        libs_available = cc_constants.LinuxAvailableLibraries
453*7594170eSAndroid Build Coastguard Worker
454*7594170eSAndroid Build Coastguard Worker    # darwin
455*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._darwin_constraint[platform_common.ConstraintValueInfo]):
456*7594170eSAndroid Build Coastguard Worker        libs_available = cc_constants.DarwinAvailableLibraries
457*7594170eSAndroid Build Coastguard Worker
458*7594170eSAndroid Build Coastguard Worker    # windows
459*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
460*7594170eSAndroid Build Coastguard Worker        libs_available = cc_constants.WindowsAvailableLibraries
461*7594170eSAndroid Build Coastguard Worker
462*7594170eSAndroid Build Coastguard Worker    bad_libs = [lib for lib in libs_in_linkopts if lib not in libs_available]
463*7594170eSAndroid Build Coastguard Worker    if bad_libs:
464*7594170eSAndroid Build Coastguard Worker        fail("Host library(s) requested via -l is not available in the toolchain. Got: %s, Supported: %s" % (bad_libs, libs_available))
465*7594170eSAndroid Build Coastguard Worker
466*7594170eSAndroid Build Coastguard Workerdef path_in_list(path, list):
467*7594170eSAndroid Build Coastguard Worker    path_parts = paths.normalize(path).split("/")
468*7594170eSAndroid Build Coastguard Worker    found = False
469*7594170eSAndroid Build Coastguard Worker    for value in list:
470*7594170eSAndroid Build Coastguard Worker        value_parts = paths.normalize(value).split("/")
471*7594170eSAndroid Build Coastguard Worker        if len(value_parts) > len(path_parts):
472*7594170eSAndroid Build Coastguard Worker            continue
473*7594170eSAndroid Build Coastguard Worker        match = True
474*7594170eSAndroid Build Coastguard Worker        for i in range(len(value_parts)):
475*7594170eSAndroid Build Coastguard Worker            if path_parts[i] != value_parts[i]:
476*7594170eSAndroid Build Coastguard Worker                match = False
477*7594170eSAndroid Build Coastguard Worker                break
478*7594170eSAndroid Build Coastguard Worker        if match == True:
479*7594170eSAndroid Build Coastguard Worker            found = True
480*7594170eSAndroid Build Coastguard Worker    return found
481