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 15load("@bazel_skylib//lib:paths.bzl", "paths") 16load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") 17load( 18 "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", 19 "action_config", 20 "tool", 21 "tool_path", 22) 23load("//build/bazel/platforms/arch/variants:constants.bzl", _arch_constants = "constants") 24load( 25 ":cc_toolchain_constants.bzl", 26 "arch_to_variants", 27 "variant_constraints", 28 "variant_name", 29 "x86_64_host_toolchains", 30 "x86_64_musl_host_toolchains", 31 "x86_host_toolchains", 32 "x86_musl_host_toolchains", 33 _actions = "actions", 34 _enabled_features = "enabled_features", 35 _generated_config_constants = "generated_config_constants", 36 _generated_sanitizer_constants = "generated_sanitizer_constants", 37) 38load( 39 ":cc_toolchain_features.bzl", 40 "get_features", 41 "int_overflow_ignorelist_filename", 42 "int_overflow_ignorelist_path", 43) 44 45# Clang-specific configuration. 46_ClangVersionInfo = provider(fields = ["clang_version", "includes"]) 47 48CLANG_TOOLS = [ 49 "llvm-ar", 50 "llvm-dwarfdump", 51 "llvm-nm", 52 "llvm-objcopy", 53 "llvm-objdump", 54 "llvm-readelf", 55 "llvm-strip", 56 "clang-tidy", 57 "clang-tidy.sh", 58 "clang-tidy.real", 59] 60 61CLANG_TEST_TOOLS = [ 62 "llvm-readelf", 63 "llvm-nm", 64] 65 66def clang_tool_output_group(tool_name): 67 return tool_name.replace("-", "_").replace(".", "_") 68 69_libclang_rt_prebuilt_map = { 70 "android_arm": "libclang_rt.builtins-arm-android.a", 71 "android_arm64": "libclang_rt.builtins-aarch64-android.a", 72 "android_x86": "libclang_rt.builtins-i686-android.a", 73 "android_x86_64": "libclang_rt.builtins-x86_64-android.a", 74 "linux_bionic_x86_64": "libclang_rt.builtins-x86_64-android.a", 75 "linux_glibc_x86": "libclang_rt.builtins-i386.a", 76 "linux_glibc_x86_64": "libclang_rt.builtins-x86_64.a", 77 "linux_musl_x86": "i686-unknown-linux-musl/lib/linux/libclang_rt.builtins-i386.a", 78 "linux_musl_x86_64": "x86_64-unknown-linux-musl/lib/linux/libclang_rt.builtins-x86_64.a", 79} 80 81_libclang_rt_ubsan_minimal_prebuilt_map = { 82 "android_arm": "libclang_rt.ubsan_minimal-arm-android.a", 83 "android_arm64": "libclang_rt.ubsan_minimal-aarch64-android.a", 84 "android_x86": "libclang_rt.ubsan_minimal-i686-android.a", 85 "android_x86_64": "libclang_rt.ubsan_minimal-x86_64-android.a", 86 "linux_bionic_x86_64": "libclang_rt.ubsan_minimal-x86_64-android.a", 87 "linux_glibc_x86": "libclang_rt.ubsan_minimal-i386.a", 88 "linux_glibc_x86_64": "libclang_rt.ubsan_minimal-x86_64.a", 89 "linux_musl_x86": "i686-unknown-linux-musl/lib/linux/libclang_rt.ubsan_minimal-i386.a", 90 "linux_musl_x86_64": "x86_64-unknown-linux-musl/lib/linux/libclang_rt.ubsan_minimal-x86_64.a", 91} 92 93def _clang_version_info_impl(ctx): 94 clang_version = ctx.attr.clang_version[BuildSettingInfo].value 95 clang_version_directory = paths.join(ctx.label.package, clang_version) 96 clang_version_dir_prefix = clang_version_directory + "/" 97 clang_short_version = ctx.attr.clang_short_version[BuildSettingInfo].value 98 99 all_files = {} # a set to do fast prebuilt lookups later 100 output_groups = { 101 "compiler_clang_includes": [], 102 "compiler_binaries": [], 103 "linker_binaries": [], 104 "ar_files": [], 105 "clang_test_tools": [], 106 } 107 108 for file in ctx.files.clang_files: 109 if not file.short_path.startswith(clang_version_dir_prefix): 110 continue 111 file_path = file.short_path.removeprefix(clang_version_dir_prefix) 112 all_files[file_path] = file 113 114 file_path_parts = file_path.split("/") 115 if file_path_parts[:2] == ["lib", "clang"] and file_path_parts[4] == "include": 116 output_groups["compiler_clang_includes"].append(file) # /lib/clang/*/include/** 117 if file_path_parts[0] == "bin" and len(file_path_parts) == 2: 118 output_groups["linker_binaries"].append(file) # /bin/* 119 if file.basename.startswith("clang"): 120 output_groups["compiler_binaries"].append(file) # /bin/clang* 121 if file.basename == "llvm-ar": 122 output_groups["ar_files"].append(file) # /bin/llvm-ar 123 if file.basename in CLANG_TEST_TOOLS: 124 output_groups["clang_test_tools"].append(file) 125 if file.basename in CLANG_TOOLS: 126 output_groups[clang_tool_output_group(file.basename)] = [file] 127 128 libclang_rt_prefix = "lib/clang/%s/lib/linux" % clang_short_version 129 for arch, path in _libclang_rt_prebuilt_map.items(): 130 file_path = paths.join(libclang_rt_prefix, path) 131 if file_path in all_files: 132 output_groups["libclang_rt_builtins_" + arch] = [all_files[file_path]] 133 else: 134 fail("could not find libclang_rt_builtin for `%s` at path `%s`" % (arch, file_path)) 135 for arch, path in _libclang_rt_ubsan_minimal_prebuilt_map.items(): 136 file_path = paths.join(libclang_rt_prefix, path) 137 if file_path in all_files: 138 output_groups["libclang_rt_ubsan_minimal_" + arch] = [all_files[file_path]] 139 else: 140 fail("could not find libclang_rt_ubsan_minimal for `%s` at path `%s`" % (arch, file_path)) 141 142 return [ 143 _ClangVersionInfo( 144 clang_version = clang_version, 145 includes = [ 146 paths.join(clang_version_directory, "lib", "clang", clang_short_version, "include"), 147 ], 148 ), 149 OutputGroupInfo( 150 **output_groups 151 ), 152 ] 153 154clang_version_info = rule( 155 implementation = _clang_version_info_impl, 156 attrs = { 157 "clang_version": attr.label(mandatory = True), 158 "clang_short_version": attr.label(mandatory = True), 159 "clang_files": attr.label_list( 160 allow_files = True, 161 ), 162 }, 163) 164 165def _tool_paths(clang_version_info): 166 return [ 167 tool_path( 168 name = "gcc", 169 path = clang_version_info.clang_version + "/bin/clang", 170 ), 171 tool_path( 172 name = "ld", 173 path = clang_version_info.clang_version + "/bin/ld.lld", 174 ), 175 tool_path( 176 name = "ar", 177 path = clang_version_info.clang_version + "/bin/llvm-ar", 178 ), 179 tool_path( 180 name = "cpp", 181 path = "/bin/false", 182 ), 183 tool_path( 184 name = "gcov", 185 path = clang_version_info.clang_version + "/bin/llvm-profdata", 186 ), 187 tool_path( 188 name = "llvm-cov", 189 path = clang_version_info.clang_version + "/bin/llvm-cov", 190 ), 191 tool_path( 192 name = "nm", 193 path = clang_version_info.clang_version + "/bin/llvm-nm", 194 ), 195 tool_path( 196 name = "objcopy", 197 path = clang_version_info.clang_version + "/bin/llvm-objcopy", 198 ), 199 tool_path( 200 name = "objdump", 201 path = clang_version_info.clang_version + "/bin/llvm-objdump", 202 ), 203 # Soong has a wrapper around strip. 204 # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/strip.go;l=62;drc=master 205 # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/builder.go;l=991-1025;drc=master 206 tool_path( 207 name = "strip", 208 path = clang_version_info.clang_version + "/bin/llvm-strip", 209 ), 210 tool_path( 211 name = "clang++", 212 path = clang_version_info.clang_version + "/bin/clang++", 213 ), 214 ] 215 216# Set tools used for all actions in Android's C++ builds. 217def _create_action_configs(tool_paths, target_os): 218 action_configs = [] 219 220 tool_name_to_tool = {} 221 for tool_path in tool_paths: 222 tool_name_to_tool[tool_path.name] = tool(path = tool_path.path) 223 224 # use clang for assembler actions 225 # https://cs.android.com/android/_/android/platform/build/soong/+/a14b18fb31eada7b8b58ecd469691c20dcb371b3:cc/builder.go;l=616;drc=769a51cc6aa9402c1c55e978e72f528c26b6a48f 226 for action_name in _actions.assemble: 227 action_configs.append(action_config( 228 action_name = action_name, 229 enabled = True, 230 tools = [tool_name_to_tool["gcc"]], 231 implies = [ 232 "user_compile_flags", 233 "compiler_input_flags", 234 "compiler_output_flags", 235 ], 236 )) 237 238 # use clang++ for compiling C++ 239 # https://cs.android.com/android/_/android/platform/build/soong/+/a14b18fb31eada7b8b58ecd469691c20dcb371b3:cc/builder.go;l=627;drc=769a51cc6aa9402c1c55e978e72f528c26b6a48f 240 action_configs.append(action_config( 241 action_name = _actions.cpp_compile, 242 enabled = True, 243 tools = [tool_name_to_tool["clang++"]], 244 implies = [ 245 "user_compile_flags", 246 "compiler_input_flags", 247 "compiler_output_flags", 248 ], 249 )) 250 251 # use clang for compiling C 252 # https://cs.android.com/android/_/android/platform/build/soong/+/a14b18fb31eada7b8b58ecd469691c20dcb371b3:cc/builder.go;l=623;drc=769a51cc6aa9402c1c55e978e72f528c26b6a48f 253 action_configs.append(action_config( 254 action_name = _actions.c_compile, 255 enabled = True, 256 # this is clang, but needs to be called gcc for legacy reasons. 257 # to avoid this, we need to set `no_legacy_features`: b/201257475 258 # http://google3/third_party/bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java;l=1106-1122;rcl=398974497 259 # http://google3/third_party/bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java;l=1185-1187;rcl=398974497 260 tools = [tool_name_to_tool["gcc"]], 261 implies = [ 262 "user_compile_flags", 263 "compiler_input_flags", 264 "compiler_output_flags", 265 ], 266 )) 267 268 rpath_features = [] 269 if target_os not in ("android", "windows"): 270 rpath_features.append("runtime_library_search_directories") 271 272 # use clang++ for dynamic linking 273 # https://cs.android.com/android/_/android/platform/build/soong/+/a14b18fb31eada7b8b58ecd469691c20dcb371b3:cc/builder.go;l=790;drc=769a51cc6aa9402c1c55e978e72f528c26b6a48f 274 for action_name in [_actions.cpp_link_dynamic_library, _actions.cpp_link_nodeps_dynamic_library]: 275 action_configs.append(action_config( 276 action_name = action_name, 277 enabled = True, 278 tools = [tool_name_to_tool["clang++"]], 279 implies = [ 280 "shared_flag", 281 "linkstamps", 282 "output_execpath_flags", 283 "library_search_directories", 284 "libraries_to_link", 285 "user_link_flags", 286 "linker_param_file", 287 ] + rpath_features, 288 )) 289 290 # use clang++ for linking cc executables 291 action_configs.append(action_config( 292 action_name = _actions.cpp_link_executable, 293 enabled = True, 294 tools = [tool_name_to_tool["clang++"]], 295 implies = [ 296 "linkstamps", 297 "output_execpath_flags", 298 "library_search_directories", 299 "libraries_to_link", 300 "user_link_flags", 301 "linker_param_file", 302 ] + rpath_features, 303 )) 304 305 # use llvm-ar for creating static archives 306 action_configs.append(action_config( 307 action_name = _actions.cpp_link_static_library, 308 enabled = True, 309 tools = [tool_name_to_tool["ar"]], 310 implies = [ 311 "linker_param_file", 312 ], 313 )) 314 315 # unused, but Bazel complains if there isn't an action config for strip 316 action_configs.append(action_config( 317 action_name = _actions.strip, 318 enabled = True, 319 tools = [tool_name_to_tool["strip"]], 320 # This doesn't imply any feature, because Bazel currently mimics 321 # Soong by running strip actions in a rule (stripped_shared_library). 322 )) 323 324 # use llvm-objcopy to remove addrsig sections from partially linked objects 325 action_configs.append(action_config( 326 action_name = "objcopy", 327 enabled = True, 328 tools = [tool_name_to_tool["objcopy"]], 329 )) 330 331 return action_configs 332 333def _cc_toolchain_config_impl(ctx): 334 clang_version_info = ctx.attr.clang_version[_ClangVersionInfo] 335 tool_paths = _tool_paths(clang_version_info) 336 337 action_configs = _create_action_configs(tool_paths, ctx.attr.target_os) 338 339 builtin_include_dirs = [] 340 builtin_include_dirs.extend(clang_version_info.includes) 341 342 # b/186035856: Do not add anything to this list. 343 builtin_include_dirs.extend(_generated_config_constants.CommonGlobalIncludes) 344 345 crt_files = struct( 346 shared_library_crtbegin = ctx.file.shared_library_crtbegin, 347 shared_library_crtend = ctx.file.shared_library_crtend, 348 shared_binary_crtbegin = ctx.file.shared_binary_crtbegin, 349 static_binary_crtbegin = ctx.file.static_binary_crtbegin, 350 binary_crtend = ctx.file.binary_crtend, 351 ) 352 353 features = get_features( 354 ctx, 355 builtin_include_dirs, 356 crt_files, 357 ) 358 359 # This is so that Bazel doesn't validate .d files against the set of headers 360 # declared in BUILD files (Blueprint files don't contain that data). %workspace%/ 361 # will be replaced with the empty string by Bazel (essentially making it relative 362 # to the build directory), so Bazel will skip the validations of all the headers 363 # in .d files. For details please see CppCompileAction.validateInclude. We add 364 # %workspace% after calling get_features so it won't be exposed as an -isystem flag. 365 builtin_include_dirs.append("%workspace%/") 366 367 return cc_common.create_cc_toolchain_config_info( 368 ctx = ctx, 369 toolchain_identifier = ctx.attr.toolchain_identifier, 370 tool_paths = tool_paths, 371 features = features, 372 action_configs = action_configs, 373 cxx_builtin_include_directories = builtin_include_dirs, 374 target_cpu = "_".join([ctx.attr.target_os, ctx.attr.target_arch]), 375 # The attributes below are required by the constructor, but don't 376 # affect actions at all. 377 host_system_name = "__toolchain_host_system_name__", 378 target_system_name = "__toolchain_target_system_name__", 379 target_libc = "__toolchain_target_libc__", 380 compiler = "__toolchain_compiler__", 381 abi_version = "__toolchain_abi_version__", 382 abi_libc_version = "__toolchain_abi_libc_version__", 383 ) 384 385_cc_toolchain_config = rule( 386 implementation = _cc_toolchain_config_impl, 387 attrs = { 388 "target_os": attr.string(mandatory = True), 389 "target_arch": attr.string(mandatory = True), 390 "toolchain_identifier": attr.string(mandatory = True), 391 "clang_version": attr.label(mandatory = True, providers = [_ClangVersionInfo]), 392 "target_flags": attr.string_list(default = []), 393 "compiler_flags": attr.string_list(default = []), 394 "linker_flags": attr.string_list(default = []), 395 "libclang_rt_builtin": attr.label(allow_single_file = True), 396 "libclang_rt_ubsan_minimal": attr.label(allow_single_file = True), 397 # crtbegin and crtend libraries for compiling cc_library_shared and 398 # cc_binary against the Bionic runtime 399 "shared_library_crtbegin": attr.label(allow_single_file = True, cfg = "target"), 400 "shared_library_crtend": attr.label(allow_single_file = True, cfg = "target"), 401 "shared_binary_crtbegin": attr.label(allow_single_file = True, cfg = "target"), 402 "static_binary_crtbegin": attr.label(allow_single_file = True, cfg = "target"), 403 "binary_crtend": attr.label(allow_single_file = True, cfg = "target"), 404 "rtti_toggle": attr.bool(default = True), 405 "_auto_zero_initialize": attr.label( 406 default = "//build/bazel/toolchains/clang/host/linux-x86:auto_zero_initialize_env", 407 ), 408 "_auto_pattern_initialize": attr.label( 409 default = "//build/bazel/toolchains/clang/host/linux-x86:auto_pattern_initialize_env", 410 ), 411 "_auto_uninitialize": attr.label( 412 default = "//build/bazel/toolchains/clang/host/linux-x86:auto_uninitialize_env", 413 ), 414 "_use_ccache": attr.label( 415 default = "//build/bazel/toolchains/clang/host/linux-x86:use_ccache_env", 416 ), 417 "_llvm_next": attr.label( 418 default = "//build/bazel/toolchains/clang/host/linux-x86:llvm_next_env", 419 ), 420 "_allow_unknown_warning_option": attr.label( 421 default = "//build/bazel/toolchains/clang/host/linux-x86:allow_unknown_warning_option_env", 422 ), 423 "_device_max_page_size_supported": attr.label( 424 default = "//build/bazel/product_config:device_max_page_size_supported", 425 ), 426 "_device_no_bionic_page_size_macro": attr.label( 427 default = "//build/bazel/product_config:device_no_bionic_page_size_macro", 428 ), 429 "_clang_default_debug_level": attr.label( 430 default = "//build/bazel/toolchains/clang/host/linux-x86:clang_default_debug_level", 431 ), 432 }, 433 provides = [CcToolchainConfigInfo], 434) 435 436# macro to expand feature flags for a toolchain 437# we do not pass these directly to the toolchain so the order can 438# be specified per toolchain 439def expand_feature_flags(arch_variant, arch_variant_to_features = {}, flag_map = {}): 440 flags = [] 441 features = _enabled_features(arch_variant, arch_variant_to_features) 442 for feature in features: 443 flags.extend(flag_map.get(feature, [])) 444 return flags 445 446# Macro to set up both the toolchain and the config. 447def android_cc_toolchain( 448 name, 449 target_os = None, 450 target_arch = None, 451 clang_version = None, 452 gcc_toolchain = None, 453 # If false, the crt version and "normal" version of this toolchain are identical. 454 crt = None, 455 libclang_rt_builtin = None, 456 libclang_rt_ubsan_minimal = None, 457 target_flags = [], 458 compiler_flags = [], 459 linker_flags = [], 460 toolchain_identifier = None, 461 rtti_toggle = True): 462 extra_linker_paths = [] 463 libclang_rt_path = None 464 if libclang_rt_builtin: 465 libclang_rt_path = libclang_rt_builtin 466 extra_linker_paths.append(libclang_rt_path) 467 libclang_rt_ubsan_minimal_path = None 468 if libclang_rt_ubsan_minimal: 469 libclang_rt_ubsan_minimal_path = libclang_rt_ubsan_minimal 470 if gcc_toolchain: 471 gcc_toolchain_path = "//%s:tools" % gcc_toolchain 472 extra_linker_paths.append(gcc_toolchain_path) 473 extra_linker_paths.append("//%s:%s" % ( 474 _generated_sanitizer_constants.CfiExportsMapPath, 475 _generated_sanitizer_constants.CfiExportsMapFilename, 476 )) 477 extra_linker_paths.append("//%s:%s" % ( 478 _generated_sanitizer_constants.CfiBlocklistPath, 479 _generated_sanitizer_constants.CfiBlocklistFilename, 480 )) 481 482 common_toolchain_config = dict( 483 [ 484 ("target_os", target_os), 485 ("target_arch", target_arch), 486 ("clang_version", clang_version), 487 ("libclang_rt_builtin", libclang_rt_path), 488 ("libclang_rt_ubsan_minimal", libclang_rt_ubsan_minimal_path), 489 ("target_flags", target_flags), 490 ("compiler_flags", compiler_flags), 491 ("linker_flags", linker_flags), 492 ("rtti_toggle", rtti_toggle), 493 ], 494 ) 495 496 _cc_toolchain_config( 497 name = "%s_nocrt_config" % name, 498 toolchain_identifier = toolchain_identifier + "_nocrt", 499 **common_toolchain_config 500 ) 501 502 # Create the filegroups needed for sandboxing toolchain inputs to C++ actions. 503 native.filegroup( 504 name = "%s_compiler_clang_includes" % name, 505 srcs = [clang_version], 506 output_group = "compiler_clang_includes", 507 ) 508 509 native.filegroup( 510 name = "%s_compiler_binaries" % name, 511 srcs = [clang_version], 512 output_group = "compiler_binaries", 513 ) 514 515 native.filegroup( 516 name = "%s_linker_binaries" % name, 517 srcs = [clang_version], 518 output_group = "linker_binaries", 519 ) 520 521 native.filegroup( 522 name = "%s_ar_files" % name, 523 srcs = [clang_version], 524 output_group = "ar_files", 525 ) 526 527 native.filegroup( 528 name = "%s_compiler_files" % name, 529 srcs = [ 530 "%s_compiler_binaries" % name, 531 "%s_compiler_clang_includes" % name, 532 "@//%s:%s" % (int_overflow_ignorelist_path, int_overflow_ignorelist_filename), 533 ], 534 ) 535 536 native.filegroup( 537 name = "%s_linker_files" % name, 538 srcs = ["%s_linker_binaries" % name] + extra_linker_paths, 539 ) 540 541 native.filegroup( 542 name = "%s_all_files" % name, 543 srcs = [ 544 "%s_compiler_files" % name, 545 "%s_linker_files" % name, 546 "%s_ar_files" % name, 547 ], 548 ) 549 550 native.cc_toolchain( 551 name = name + "_nocrt", 552 all_files = "%s_all_files" % name, 553 as_files = "//:empty", # Note the "//" prefix, see comment above 554 ar_files = "%s_ar_files" % name, 555 compiler_files = "%s_compiler_files" % name, 556 dwp_files = ":empty", 557 linker_files = "%s_linker_files" % name, 558 objcopy_files = ":empty", 559 strip_files = ":empty", 560 supports_param_files = 0, 561 toolchain_config = ":%s_nocrt_config" % name, 562 toolchain_identifier = toolchain_identifier + "_nocrt", 563 ) 564 565 if crt: 566 # Write the toolchain config. 567 _cc_toolchain_config( 568 name = "%s_config" % name, 569 toolchain_identifier = toolchain_identifier, 570 shared_library_crtbegin = crt.shared_library_crtbegin, 571 shared_library_crtend = crt.shared_library_crtend, 572 shared_binary_crtbegin = crt.shared_binary_crtbegin, 573 static_binary_crtbegin = crt.static_binary_crtbegin, 574 binary_crtend = crt.binary_crtend, 575 **common_toolchain_config 576 ) 577 578 native.filegroup( 579 name = "%s_crt_libs" % name, 580 srcs = [ 581 crt.shared_library_crtbegin, 582 crt.shared_library_crtend, 583 crt.shared_binary_crtbegin, 584 crt.static_binary_crtbegin, 585 crt.binary_crtend, 586 ], 587 ) 588 589 native.filegroup( 590 name = "%s_linker_files_with_crt" % name, 591 srcs = [ 592 "%s_linker_files" % name, 593 "%s_crt_libs" % name, 594 ], 595 ) 596 597 # Create the actual cc_toolchain. 598 # The dependency on //:empty is intentional; it's necessary so that Bazel 599 # can parse .d files correctly (see the comment in $TOP/BUILD) 600 native.cc_toolchain( 601 name = name, 602 all_files = "%s_all_files" % name, 603 as_files = "//:empty", # Note the "//" prefix, see comment above 604 ar_files = "%s_ar_files" % name, 605 compiler_files = "%s_compiler_files" % name, 606 dwp_files = ":empty", 607 linker_files = "%s_linker_files_with_crt" % name, 608 objcopy_files = ":empty", 609 strip_files = ":empty", 610 supports_param_files = 0, 611 toolchain_config = ":%s_config" % name, 612 toolchain_identifier = toolchain_identifier, 613 exec_transition_for_inputs = False, 614 ) 615 else: 616 _cc_toolchain_config( 617 name = "%s_config" % name, 618 toolchain_identifier = toolchain_identifier, 619 **common_toolchain_config 620 ) 621 622 native.alias( 623 name = name, 624 actual = name + "_nocrt", 625 ) 626 627def _toolchain_name(arch, variant, nocrt = False): 628 return "cc_toolchain_{arch}{variant}{nocrt}_def".format( 629 arch = arch, 630 variant = variant_name(variant), 631 nocrt = "_nocrt" if nocrt else "", 632 ) 633 634def toolchain_definition(arch, variant, nocrt = False): 635 """Macro to create a toolchain with a standardized name 636 637 The name used here must match that used in cc_register_toolchains. 638 """ 639 name = _toolchain_name(arch, variant, nocrt) 640 native.toolchain( 641 name = name, 642 exec_compatible_with = [ 643 "//build/bazel_common_rules/platforms/arch:x86_64", 644 "//build/bazel_common_rules/platforms/os:linux", 645 ], 646 target_compatible_with = [ 647 "//build/bazel_common_rules/platforms/arch:%s" % arch, 648 "//build/bazel_common_rules/platforms/os:android", 649 ] + variant_constraints( 650 variant, 651 _arch_constants.AndroidArchToVariantToFeatures[arch], 652 ), 653 toolchain = ":cc_toolchain_{arch}{variant}{nocrt}".format( 654 arch = arch, 655 variant = variant_name(variant), 656 nocrt = "_nocrt" if nocrt else "", 657 ), 658 toolchain_type = ( 659 ":nocrt_toolchain" if nocrt else "@bazel_tools//tools/cpp:toolchain_type" 660 ), 661 ) 662 663def cc_register_toolchains(): 664 """Register cc_toolchains for device and host platforms. 665 666 This function ensures that generic (non-variant) device toolchains are 667 registered last. 668 """ 669 670 generic_toolchains = [] 671 arch_variant_toolchains = [] 672 cpu_variant_toolchains = [] 673 for arch, variants in arch_to_variants.items(): 674 for variant in variants: 675 if not variant.arch_variant: 676 generic_toolchains.append((arch, variant)) 677 elif not variant.cpu_variant: 678 arch_variant_toolchains.append((arch, variant)) 679 else: 680 cpu_variant_toolchains.append((arch, variant)) 681 682 target_toolchains = [ 683 _toolchain_name(arch, variant, nocrt = nocrt) 684 for nocrt in [False, True] 685 for arch, variant in ( 686 # Ordering is important here: more specific toolchains must be 687 # registered before more generic toolchains 688 cpu_variant_toolchains + 689 arch_variant_toolchains + 690 generic_toolchains 691 ) 692 ] 693 694 host_toolchains = [ 695 tc[0] + "_def" 696 for tc in x86_64_host_toolchains + x86_host_toolchains + 697 x86_64_musl_host_toolchains + x86_musl_host_toolchains 698 ] 699 700 native.register_toolchains(*[ 701 "//prebuilts/clang/host/linux-x86:" + tc 702 for tc in host_toolchains + target_toolchains 703 ]) 704