xref: /aosp_15_r20/build/bazel/rules/cc/ndk_headers.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2023 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 Worker"""
16*7594170eSAndroid Build Coastguard Worker`ndk_headers` provides a CcInfo for building SDK variants of CC libraries.
17*7594170eSAndroid Build Coastguard WorkerUnlike cc_library_headers, it has a `from` and `to` attribute that can be used to create an import path for headers that
18*7594170eSAndroid Build Coastguard Workeris different than the checked-in folder layout.
19*7594170eSAndroid Build Coastguard Worker"""
20*7594170eSAndroid Build Coastguard Worker
21*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths")
22*7594170eSAndroid Build Coastguard Worker
23*7594170eSAndroid Build Coastguard Worker_VERSIONER_DEPS_DIR = "bionic/libc/versioner-dependencies"
24*7594170eSAndroid Build Coastguard Worker
25*7594170eSAndroid Build Coastguard Worker# Creates an action to copy NDK headers to out/ after handling {strip}_import_prefix
26*7594170eSAndroid Build Coastguard Worker# Return a tuple with the following elements
27*7594170eSAndroid Build Coastguard Worker# 1. root of the synthetic dir (this will become -isystem/-I)
28*7594170eSAndroid Build Coastguard Worker# 2. list of hdr files in out
29*7594170eSAndroid Build Coastguard Workerdef _assemeble_headers(ctx):
30*7594170eSAndroid Build Coastguard Worker    out_dir = paths.join(
31*7594170eSAndroid Build Coastguard Worker        ctx.bin_dir.path,
32*7594170eSAndroid Build Coastguard Worker        ctx.label.package,
33*7594170eSAndroid Build Coastguard Worker        ctx.label.name,
34*7594170eSAndroid Build Coastguard Worker    )
35*7594170eSAndroid Build Coastguard Worker
36*7594170eSAndroid Build Coastguard Worker    outs = []
37*7594170eSAndroid Build Coastguard Worker    for hdr in ctx.files.hdrs:
38*7594170eSAndroid Build Coastguard Worker        rel_to_package = paths.relativize(
39*7594170eSAndroid Build Coastguard Worker            hdr.path,
40*7594170eSAndroid Build Coastguard Worker            ctx.label.package,
41*7594170eSAndroid Build Coastguard Worker        )
42*7594170eSAndroid Build Coastguard Worker        rel_after_strip_import = paths.relativize(
43*7594170eSAndroid Build Coastguard Worker            rel_to_package,
44*7594170eSAndroid Build Coastguard Worker            ctx.attr.strip_import_prefix,
45*7594170eSAndroid Build Coastguard Worker        )
46*7594170eSAndroid Build Coastguard Worker        out = ctx.actions.declare_file(
47*7594170eSAndroid Build Coastguard Worker            paths.join(
48*7594170eSAndroid Build Coastguard Worker                ctx.label.name,
49*7594170eSAndroid Build Coastguard Worker                ctx.attr.import_prefix,
50*7594170eSAndroid Build Coastguard Worker                rel_after_strip_import,
51*7594170eSAndroid Build Coastguard Worker            ),
52*7594170eSAndroid Build Coastguard Worker        )
53*7594170eSAndroid Build Coastguard Worker
54*7594170eSAndroid Build Coastguard Worker        ctx.actions.run_shell(
55*7594170eSAndroid Build Coastguard Worker            inputs = depset(direct = [hdr]),
56*7594170eSAndroid Build Coastguard Worker            outputs = [out],
57*7594170eSAndroid Build Coastguard Worker            command = "cp -f %s %s" % (hdr.path, out.path),
58*7594170eSAndroid Build Coastguard Worker            mnemonic = "CopyFile",
59*7594170eSAndroid Build Coastguard Worker            use_default_shell_env = True,
60*7594170eSAndroid Build Coastguard Worker        )
61*7594170eSAndroid Build Coastguard Worker        outs.append(out)
62*7594170eSAndroid Build Coastguard Worker
63*7594170eSAndroid Build Coastguard Worker    return out_dir, outs
64*7594170eSAndroid Build Coastguard Worker
65*7594170eSAndroid Build Coastguard Worker# Creates an action to run versioner on the assembled NDK headers
66*7594170eSAndroid Build Coastguard Worker# Used for libc
67*7594170eSAndroid Build Coastguard Worker# Return a tuple with the following elements
68*7594170eSAndroid Build Coastguard Worker# 1. root of the synthetic dir (this will become -isystem/-I)
69*7594170eSAndroid Build Coastguard Worker# 2. list of hdr files in out
70*7594170eSAndroid Build Coastguard Workerdef _version_headers(ctx, assembled_out_dir, assembled_hdrs):
71*7594170eSAndroid Build Coastguard Worker    out_dir = assembled_out_dir + ".versioned"
72*7594170eSAndroid Build Coastguard Worker    outs = []
73*7594170eSAndroid Build Coastguard Worker
74*7594170eSAndroid Build Coastguard Worker    for assembled_hdr in assembled_hdrs:
75*7594170eSAndroid Build Coastguard Worker        rel = paths.relativize(
76*7594170eSAndroid Build Coastguard Worker            assembled_hdr.path,
77*7594170eSAndroid Build Coastguard Worker            assembled_out_dir,
78*7594170eSAndroid Build Coastguard Worker        )
79*7594170eSAndroid Build Coastguard Worker        out = ctx.actions.declare_file(
80*7594170eSAndroid Build Coastguard Worker            paths.join(
81*7594170eSAndroid Build Coastguard Worker                ctx.label.name + ".versioned",
82*7594170eSAndroid Build Coastguard Worker                rel,
83*7594170eSAndroid Build Coastguard Worker            ),
84*7594170eSAndroid Build Coastguard Worker        )
85*7594170eSAndroid Build Coastguard Worker        outs.append(out)
86*7594170eSAndroid Build Coastguard Worker
87*7594170eSAndroid Build Coastguard Worker    args = ctx.actions.args()
88*7594170eSAndroid Build Coastguard Worker    args.add_all(["-o", out_dir, assembled_out_dir, _VERSIONER_DEPS_DIR])
89*7594170eSAndroid Build Coastguard Worker
90*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
91*7594170eSAndroid Build Coastguard Worker        executable = ctx.executable._versioner,
92*7594170eSAndroid Build Coastguard Worker        arguments = [args],
93*7594170eSAndroid Build Coastguard Worker        inputs = assembled_hdrs,
94*7594170eSAndroid Build Coastguard Worker        outputs = outs,
95*7594170eSAndroid Build Coastguard Worker        mnemonic = "VersionBionicHeaders",
96*7594170eSAndroid Build Coastguard Worker        tools = ctx.files._versioner_include_deps,
97*7594170eSAndroid Build Coastguard Worker    )
98*7594170eSAndroid Build Coastguard Worker
99*7594170eSAndroid Build Coastguard Worker    return out_dir, outs
100*7594170eSAndroid Build Coastguard Worker
101*7594170eSAndroid Build Coastguard Worker# Keep in sync with
102*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/config/toolchain.go;l=120-127;drc=1717b3bb7a49c52b26c90469f331b55f7b681690;bpv=1;bpt=0
103*7594170eSAndroid Build Coastguard Workerdef _ndk_triple(ctx):
104*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._arm_constraint[platform_common.ConstraintValueInfo]):
105*7594170eSAndroid Build Coastguard Worker        return "arm-linux-androideabi"
106*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._arm64_constraint[platform_common.ConstraintValueInfo]):
107*7594170eSAndroid Build Coastguard Worker        return "aarch64-linux-android"
108*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._riscv64_constraint[platform_common.ConstraintValueInfo]):
109*7594170eSAndroid Build Coastguard Worker        return "riscv64-linux-android"
110*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._x86_constraint[platform_common.ConstraintValueInfo]):
111*7594170eSAndroid Build Coastguard Worker        return "i686-linux-android"
112*7594170eSAndroid Build Coastguard Worker    if ctx.target_platform_has_constraint(ctx.attr._x86_64_constraint[platform_common.ConstraintValueInfo]):
113*7594170eSAndroid Build Coastguard Worker        return "x86_64-linux-android"
114*7594170eSAndroid Build Coastguard Worker    fail("Could not determine NDK triple: unrecognized arch")
115*7594170eSAndroid Build Coastguard Worker
116*7594170eSAndroid Build Coastguard Workerdef _ndk_headers_impl(ctx):
117*7594170eSAndroid Build Coastguard Worker    # Copy the hdrs to a synthetic root
118*7594170eSAndroid Build Coastguard Worker    out_dir, outs = _assemeble_headers(ctx)
119*7594170eSAndroid Build Coastguard Worker    if ctx.attr.run_versioner:
120*7594170eSAndroid Build Coastguard Worker        # Version the copied headers
121*7594170eSAndroid Build Coastguard Worker        out_dir, outs = _version_headers(ctx, out_dir, outs)
122*7594170eSAndroid Build Coastguard Worker
123*7594170eSAndroid Build Coastguard Worker    compilation_context = cc_common.create_compilation_context(
124*7594170eSAndroid Build Coastguard Worker        headers = depset(outs),
125*7594170eSAndroid Build Coastguard Worker        # ndk_headers are provided as -isystem and not -I
126*7594170eSAndroid Build Coastguard Worker        # https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/compiler.go;l=394-403;drc=e0202c4823d1b3cabf63206d3a6611868d1559e1;bpv=1;bpt=0
127*7594170eSAndroid Build Coastguard Worker        system_includes = depset([
128*7594170eSAndroid Build Coastguard Worker            out_dir,
129*7594170eSAndroid Build Coastguard Worker            paths.join(out_dir, _ndk_triple(ctx)),
130*7594170eSAndroid Build Coastguard Worker        ]),
131*7594170eSAndroid Build Coastguard Worker    )
132*7594170eSAndroid Build Coastguard Worker    return [
133*7594170eSAndroid Build Coastguard Worker        DefaultInfo(files = depset(outs)),
134*7594170eSAndroid Build Coastguard Worker        CcInfo(compilation_context = compilation_context),
135*7594170eSAndroid Build Coastguard Worker    ]
136*7594170eSAndroid Build Coastguard Worker
137*7594170eSAndroid Build Coastguard Workerndk_headers = rule(
138*7594170eSAndroid Build Coastguard Worker    implementation = _ndk_headers_impl,
139*7594170eSAndroid Build Coastguard Worker    attrs = {
140*7594170eSAndroid Build Coastguard Worker        "strip_import_prefix": attr.string(
141*7594170eSAndroid Build Coastguard Worker            doc =
142*7594170eSAndroid Build Coastguard Worker                """
143*7594170eSAndroid Build Coastguard Worker            The prefix to strip from the .h files of this target.
144*7594170eSAndroid Build Coastguard Worker            e.g if the hdrs are `dir/foo.h` and strip_import_prefix is `dir`, then rdeps will include it as #include <foo.h>
145*7594170eSAndroid Build Coastguard Worker            """,
146*7594170eSAndroid Build Coastguard Worker            default = "",
147*7594170eSAndroid Build Coastguard Worker        ),
148*7594170eSAndroid Build Coastguard Worker        "import_prefix": attr.string(
149*7594170eSAndroid Build Coastguard Worker            doc =
150*7594170eSAndroid Build Coastguard Worker                """
151*7594170eSAndroid Build Coastguard Worker            The prefix to add to the .h files of this target.
152*7594170eSAndroid Build Coastguard Worker            e.g if the hdrs are `dir/foo.h` and import_prefix is `dir_prefix`, then rdeps will include it as #include <dir_prefix/dir/foo.h>
153*7594170eSAndroid Build Coastguard Worker            """,
154*7594170eSAndroid Build Coastguard Worker            default = "",
155*7594170eSAndroid Build Coastguard Worker        ),
156*7594170eSAndroid Build Coastguard Worker        "hdrs": attr.label_list(
157*7594170eSAndroid Build Coastguard Worker            doc = ".h files contributed by the library to the Public API surface (NDK)",
158*7594170eSAndroid Build Coastguard Worker            allow_files = True,
159*7594170eSAndroid Build Coastguard Worker        ),
160*7594170eSAndroid Build Coastguard Worker        "run_versioner": attr.bool(
161*7594170eSAndroid Build Coastguard Worker            doc = "Run versioner with bionic/libc/versioner-dependencies on the include path. Used only by libc",
162*7594170eSAndroid Build Coastguard Worker            default = False,
163*7594170eSAndroid Build Coastguard Worker        ),
164*7594170eSAndroid Build Coastguard Worker        "_versioner": attr.label(
165*7594170eSAndroid Build Coastguard Worker            executable = True,
166*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
167*7594170eSAndroid Build Coastguard Worker            default = Label("//prebuilts/clang-tools:versioner"),
168*7594170eSAndroid Build Coastguard Worker        ),
169*7594170eSAndroid Build Coastguard Worker        "_versioner_include_deps": attr.label(
170*7594170eSAndroid Build Coastguard Worker            doc = "Filegroup containing the .h files placed on the include path when running versioner",
171*7594170eSAndroid Build Coastguard Worker            default = Label("//bionic/libc:versioner-dependencies"),
172*7594170eSAndroid Build Coastguard Worker        ),
173*7594170eSAndroid Build Coastguard Worker        "_arm_constraint": attr.label(
174*7594170eSAndroid Build Coastguard Worker            default = Label("//build/bazel_common_rules/platforms/arch:arm"),
175*7594170eSAndroid Build Coastguard Worker        ),
176*7594170eSAndroid Build Coastguard Worker        "_arm64_constraint": attr.label(
177*7594170eSAndroid Build Coastguard Worker            default = Label("//build/bazel_common_rules/platforms/arch:arm64"),
178*7594170eSAndroid Build Coastguard Worker        ),
179*7594170eSAndroid Build Coastguard Worker        "_riscv64_constraint": attr.label(
180*7594170eSAndroid Build Coastguard Worker            default = Label("//build/bazel_common_rules/platforms/arch:riscv64"),
181*7594170eSAndroid Build Coastguard Worker        ),
182*7594170eSAndroid Build Coastguard Worker        "_x86_constraint": attr.label(
183*7594170eSAndroid Build Coastguard Worker            default = Label("//build/bazel_common_rules/platforms/arch:x86"),
184*7594170eSAndroid Build Coastguard Worker        ),
185*7594170eSAndroid Build Coastguard Worker        "_x86_64_constraint": attr.label(
186*7594170eSAndroid Build Coastguard Worker            default = Label("//build/bazel_common_rules/platforms/arch:x86_64"),
187*7594170eSAndroid Build Coastguard Worker        ),
188*7594170eSAndroid Build Coastguard Worker    },
189*7594170eSAndroid Build Coastguard Worker    provides = [CcInfo],
190*7594170eSAndroid Build Coastguard Worker)
191