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