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 15# Helpers for stl property resolution. 16# These mappings taken from build/soong/cc/stl.go 17 18load("//build/bazel/platforms/arch/variants:constants.bzl", "arch_variant_to_constraints") 19 20_libcpp_stl_names = { 21 "libc++": True, 22 "libc++_static": True, 23 "": True, 24 "system": True, 25} 26 27# https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/stl.go;l=162;drc=cb0ac95bde896fa2aa59193a37ceb580758c322c 28# this should vary based on vndk version 29# skip libm and libc because then we would have duplicates due to system_shared_library 30_libunwind = "//prebuilts/clang/host/linux-x86:libunwind" 31 32_ndk_system = "//prebuilts/ndk:ndk_system" 33 34_static_binary_deps = select({ 35 arch_variant_to_constraints["android"]: [_libunwind], 36 arch_variant_to_constraints["linux_bionic"]: [_libunwind], 37 "//build/bazel/rules/apex:unbundled_app": [], 38 "//conditions:default": [], 39}) 40 41def _stl_name_resolver(stl_name, is_shared): 42 if stl_name == "none": 43 return stl_name 44 45 if stl_name not in _libcpp_stl_names: 46 fail("Unhandled stl %s" % stl_name) 47 48 if stl_name in ("", "system"): 49 if is_shared: 50 stl_name = "libc++" 51 else: 52 stl_name = "libc++_static" 53 return stl_name 54 55def stl_info_from_attr(stl_name, is_shared, is_binary = False): 56 deps = _stl_deps(stl_name, is_shared, is_binary) 57 flags = _stl_flags(stl_name, is_shared) 58 return struct( 59 static_deps = deps.static, 60 shared_deps = deps.shared, 61 deps = deps.deps, 62 cppflags = flags.cppflags, 63 linkopts = flags.linkopts, 64 ) 65 66def _stl_deps(stl_name, is_shared, is_binary = False): 67 if stl_name == "none": 68 return struct(static = [], shared = [], deps = []) 69 70 shared, static, deps = [], [], [] 71 if stl_name in ("", "system"): 72 if is_shared: 73 shared = select({ 74 # non-sdk variant, effective STL is libc++ 75 arch_variant_to_constraints["android"]: [ 76 "//external/libcxx:libc++", 77 ], 78 # sdk variant, effective STL is ndk_system 79 "//build/bazel/rules/apex:unbundled_app": [ 80 "//bionic/libc:libstdc++", 81 ], 82 "//conditions:default": ["//external/libcxx:libc++"], # libc++ is used by host variants 83 }) 84 static = select({ 85 arch_variant_to_constraints["android"]: [ 86 "//external/libcxxabi:libc++demangle", 87 ], 88 # sdk variant does not have an entry since ndk_system's deps have been added in `shared` 89 "//build/bazel/rules/apex:unbundled_app": [], 90 "//conditions:default": [], 91 }) 92 deps = select({ 93 # sdk variant, effective STL is ndk_system 94 "//build/bazel/rules/apex:unbundled_app": [ 95 _ndk_system, 96 ], 97 "//conditions:default": [], 98 }) 99 100 else: 101 shared = select({ 102 # sdk variant, effective STL is ndk_system 103 "//build/bazel/rules/apex:unbundled_app": [ 104 "//bionic/libc:libstdc++", 105 ], 106 "//conditions:default": [], 107 }) 108 static = select({ 109 # non-sdk variant, effective STL is libc++_static 110 arch_variant_to_constraints["android"]: [ 111 "//external/libcxx:libc++_static", 112 "//external/libcxxabi:libc++demangle", 113 ], 114 # sdk variant does not have an entry since ndk_system's deps have been added in `shared` 115 "//build/bazel/rules/apex:unbundled_app": [], 116 "//conditions:default": ["//external/libcxx:libc++_static"], # libc++_static is used by host variants 117 }) 118 deps = select({ 119 # sdk variant, effective STL is ndk_system 120 "//build/bazel/rules/apex:unbundled_app": [ 121 _ndk_system, 122 ], 123 "//conditions:default": [], 124 }) 125 elif stl_name == "libc++": 126 shared = select({ 127 arch_variant_to_constraints["android"]: [ 128 "//external/libcxx:libc++", 129 ], 130 # sdk variant, effective STL is ndk_libc++_shared 131 "//build/bazel/rules/apex:unbundled_app": [ 132 "//prebuilts/ndk:ndk_libc++_shared", 133 ], 134 "//conditions:default": ["//external/libcxx:libc++"], # libc++ is used by host variants 135 }) 136 static = select({ 137 arch_variant_to_constraints["android"]: [ 138 "//external/libcxxabi:libc++demangle", 139 ], 140 "//build/bazel/rules/apex:unbundled_app": [ 141 "//prebuilts/ndk:ndk_libunwind", 142 ], 143 "//conditions:default": [], 144 }) 145 146 elif stl_name == "libc++_static": 147 static = select({ 148 arch_variant_to_constraints["android"]: [ 149 "//external/libcxx:libc++_static", 150 "//external/libcxxabi:libc++demangle", 151 ], 152 # sdk variant, effective STL is ndk_libc++_static 153 "//build/bazel/rules/apex:unbundled_app": [ 154 "//prebuilts/ndk:ndk_libc++_static", 155 "//prebuilts/ndk:ndk_libc++abi", 156 "//prebuilts/ndk:ndk_libunwind", 157 ], 158 "//conditions:default": ["//external/libcxx:libc++_static"], # libc++_static is used by host variants 159 }) 160 if is_binary: 161 static += _static_binary_deps 162 return struct( 163 static = static, 164 shared = shared, 165 deps = deps, 166 ) 167 168def _stl_flags(stl_name, is_shared): 169 """returns flags that control STL inclusion 170 171 Should be kept up to date with 172 https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/stl.go;l=197;drc=8722ca5486fa62c07520e09db54b1b330b48da17 173 174 Args: 175 stl_name: string, name of STL library to use 176 is_shared: bool, if true, the STL should be linked dynamically 177 Returns: 178 struct containing flags for CC compilation 179 """ 180 stl_name = _stl_name_resolver(stl_name, is_shared) 181 182 cppflags_darwin = [] 183 cppflags_windows_not_bionic = [] 184 cppflags_not_bionic = [] 185 linkopts_not_bionic = [] 186 if stl_name in ("libc++", "libc++_static"): 187 cppflags_not_bionic.append("-nostdinc++") 188 linkopts_not_bionic.append("-nostdlib++") 189 190 # libc++'s headers are annotated with availability macros that 191 # indicate which version of Mac OS was the first to ship with a 192 # libc++ feature available in its *system's* libc++.dylib. We do 193 # not use the system's library, but rather ship our own. As such, 194 # these availability attributes are meaningless for us but cause 195 # build breaks when we try to use code that would not be available 196 # in the system's dylib. 197 cppflags_darwin.append("-D_LIBCPP_DISABLE_AVAILABILITY") 198 199 # Disable visiblity annotations since we're using static libc++. 200 cppflags_windows_not_bionic.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS") 201 cppflags_windows_not_bionic.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS") 202 203 # Use Win32 threads in libc++. 204 cppflags_windows_not_bionic.append("-D_LIBCPP_HAS_THREAD_API_WIN32") 205 elif stl_name in ("none"): 206 cppflags_not_bionic.append("-nostdinc++") 207 linkopts_not_bionic.append("-nostdlib++") 208 else: 209 #TODO(b/201079053) handle ndk STL flags 210 pass 211 212 return struct( 213 cppflags = select({ 214 "//build/bazel_common_rules/platforms/os:bionic": [], 215 "//build/bazel/rules/apex:unbundled_app": [], 216 "//conditions:default": cppflags_not_bionic, 217 }) + select({ 218 "//build/bazel_common_rules/platforms/os:darwin": cppflags_darwin, 219 "//build/bazel_common_rules/platforms/os:windows": ( 220 cppflags_windows_not_bionic 221 ), 222 "//conditions:default": [], 223 }), 224 linkopts = select({ 225 "//build/bazel_common_rules/platforms/os:bionic": [], 226 "//build/bazel/rules/apex:unbundled_app": [], 227 "//build/bazel/rules/apex:unbundled_app.arm": ["-Wl,--exclude-libs,libunwind.a"], 228 "//conditions:default": linkopts_not_bionic, 229 }), 230 ) 231