1# Copyright 2023 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://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, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") 16load("@bazel_skylib//rules:copy_file.bzl", "copy_file") 17load("@rules_cc//cc/toolchains:args.bzl", "cc_args") 18load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") 19load("@rules_cc//cc/toolchains:feature_constraint.bzl", "cc_feature_constraint") 20load("@rules_cc//cc/toolchains:feature_set.bzl", "cc_feature_set") 21load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain") 22load("//pw_toolchain/cc:builtin_module_map.bzl", "builtin_module_map") 23load("//pw_toolchain/host_clang:paths.bzl", "LLVM_TOOLCHAIN") 24 25package(default_visibility = ["//visibility:public"]) 26 27licenses(["notice"]) 28 29filegroup(name = "empty") 30 31cc_args( 32 name = "link_with_lld", 33 actions = ["@rules_cc//cc/toolchains/actions:link_actions"], 34 args = ["-fuse-ld=lld"], 35) 36 37cc_args( 38 name = "macos_link_libs", 39 actions = ["@rules_cc//cc/toolchains/actions:link_actions"], 40 args = [ 41 # Force dropping the system libc++. 42 "-nostdlib++", 43 # Use libc++ provided by the toolchain. 44 LLVM_TOOLCHAIN + "/lib/libc++.a", 45 ], 46 target_compatible_with = ["@platforms//os:macos"], 47) 48 49cc_args( 50 name = "linux_link_libs", 51 actions = ["@rules_cc//cc/toolchains/actions:link_actions"], 52 args = [ 53 "-pthread", 54 "-stdlib=libc++", 55 "--rtlib=compiler-rt", 56 "--unwindlib=libunwind", 57 ], 58 target_compatible_with = ["@platforms//os:linux"], 59) 60 61cc_args( 62 name = "libtool_darwin_flags", 63 actions = ["@rules_cc//cc/toolchains/actions:cpp_link_static_library"], 64 args = ["-no_warning_for_no_symbols"], 65) 66 67# Thread safety warnings are only supported by Clang. 68cc_args( 69 name = "thread_safety_warnings", 70 actions = [ 71 "@rules_cc//cc/toolchains/actions:c_compile_actions", 72 "@rules_cc//cc/toolchains/actions:cpp_compile_actions", 73 ], 74 args = [ 75 "-Wthread-safety", 76 "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1", 77 ], 78) 79 80cc_args( 81 name = "verbose_compiler_flags", 82 actions = [ 83 "@rules_cc//cc/toolchains/actions:compile_actions", 84 "@rules_cc//cc/toolchains/actions:link_actions", 85 ], 86 args = ["-v"], 87) 88 89# A feature that can be easily toggled to include extra compiler output to help 90# debug things like include search path ordering and showing all the flags 91# passed to the compiler. 92# 93# Add `--features=verbose_compiler_output` to your Bazel invocation to enable. 94cc_feature( 95 name = "verbose_compiler_output", 96 args = [":verbose_compiler_flags"], 97 feature_name = "verbose_compiler_output", 98) 99 100cc_args( 101 name = "no_unknown_warning_option", 102 actions = [ 103 "@rules_cc//cc/toolchains/actions:c_compile_actions", 104 "@rules_cc//cc/toolchains/actions:cpp_compile_actions", 105 ], 106 args = [ 107 "-Wno-unknown-warning-option", 108 ], 109) 110 111bool_flag( 112 name = "asan", 113 build_setting_default = False, 114) 115 116config_setting( 117 name = "asan_enabled", 118 flag_values = { 119 ":asan": "true", 120 }, 121) 122 123cc_feature( 124 name = "asan_feature", 125 args = ["//pw_toolchain/cc/args:asan"], 126 feature_name = "asan", 127 requires_any_of = [":asan_constraint"], 128) 129 130cc_feature_set( 131 name = "asan_constraint", 132 # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure 133 # -fsanitize=address is not be specified during Rust linking. 134 all_of = [":rules_rust_unsupported_feature"], 135) 136 137bool_flag( 138 name = "ubsan", 139 build_setting_default = False, 140) 141 142config_setting( 143 name = "ubsan_enabled", 144 flag_values = { 145 ":ubsan": "true", 146 }, 147) 148 149cc_feature( 150 name = "ubsan_feature", 151 args = ["//pw_toolchain/cc/args:ubsan"], 152 feature_name = "ubsan", 153 requires_any_of = [":ubsan_constraint"], 154) 155 156cc_feature_set( 157 name = "ubsan_constraint", 158 # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure 159 # -fsanitize=undefined is not be specified during Rust linking. 160 all_of = [":rules_rust_unsupported_feature"], 161) 162 163bool_flag( 164 name = "tsan", 165 build_setting_default = False, 166) 167 168config_setting( 169 name = "tsan_enabled", 170 flag_values = { 171 ":tsan": "true", 172 }, 173) 174 175cc_feature( 176 name = "tsan_feature", 177 args = ["//pw_toolchain/cc/args:tsan"], 178 feature_name = "tsan", 179 requires_any_of = [":tsan_constraint"], 180) 181 182cc_feature_set( 183 name = "tsan_constraint", 184 # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure 185 # -fsanitize=undefined is not be specified during Rust linking. 186 all_of = [":rules_rust_unsupported_feature"], 187) 188 189bool_flag( 190 name = "fuzztest", 191 build_setting_default = False, 192) 193 194config_setting( 195 name = "fuzztest_enabled", 196 flag_values = { 197 ":fuzztest": "true", 198 }, 199) 200 201cc_feature( 202 name = "fuzztest_feature", 203 args = ["//pw_toolchain/cc/args:fuzztest"], 204 feature_name = "fuzztest", 205) 206 207# This is a sentinel feature defined by rules_rust. It is by definition 208# unsupported: rules_rust will disable this feature when linking Rust code. 209cc_feature( 210 name = "rules_rust_unsupported_feature", 211 feature_name = "rules_rust_unsupported_feature", 212) 213 214# This is a sentinel feature defined by rules_go. It is by definition 215# unsupported: rules_go will disable this feature when linking Go code. 216cc_feature( 217 name = "rules_go_unsupported_feature", 218 feature_name = "rules_go_unsupported_feature", 219) 220 221cc_feature_constraint( 222 name = "rules_go_constraint", 223 224 # This constraint is saying "not not Golang" (yes Golang / only Golang). 225 none_of = [":rules_go_unsupported_feature"], 226) 227 228# Golang doesn't link with PIE enabled. See pwbug.dev/347708308. 229# 230# We want to disable PIE only when we're *not* compiling Golang code. 231cc_args( 232 name = "no_pie_for_go_flags", 233 actions = ["@rules_cc//cc/toolchains/actions:link_actions"], 234 args = [ 235 "-no-pie", 236 ], 237 requires_any_of = [":rules_go_constraint"], 238 target_compatible_with = ["@platforms//os:linux"], 239) 240 241cc_args( 242 name = "silence_cgo_warnings", 243 actions = [ 244 "@rules_cc//cc/toolchains/actions:compile_actions", 245 "@rules_cc//cc/toolchains/actions:link_actions", 246 ], 247 args = ["-Wno-unused-parameter"], 248 requires_any_of = [":rules_go_constraint"], 249) 250 251cc_feature( 252 name = "supports_pic", 253 feature_name = "supports_pic", 254) 255 256# Symlink to clangd, for user convenience. 257copy_file( 258 name = "copy_clangd", 259 src = select({ 260 "@platforms//os:macos": "@llvm_toolchain_macos//:bin/clangd", 261 "//conditions:default": "@llvm_toolchain//:bin/clangd", 262 }), 263 out = "clangd", 264 allow_symlink = True, 265) 266 267# Symlink to clang-tidy, for user convenience. 268copy_file( 269 name = "copy_clang_tidy", 270 src = select({ 271 "@platforms//os:macos": "@llvm_toolchain_macos//:clang-tidy", 272 "//conditions:default": "@llvm_toolchain//:clang-tidy", 273 }), 274 out = "clang-tidy", 275 allow_symlink = True, 276 is_executable = True, 277) 278 279cc_feature( 280 name = "use_module_maps", 281 args = ["//pw_toolchain/cc/args:dependent_module_map_files"], 282 feature_name = "use_module_maps", 283 requires_any_of = [":module_maps"], 284) 285 286cc_feature( 287 name = "module_maps", 288 feature_name = "module_maps", 289) 290 291cc_feature( 292 name = "layering_check_feature", 293 args = [ 294 "//pw_toolchain/cc/args:layering_check", 295 "//pw_toolchain/cc/args:module_name", 296 "//pw_toolchain/cc/args:module_map_file", 297 ], 298 feature_name = "layering_check", 299 implies = [":use_module_maps"], 300) 301 302bool_flag( 303 name = "layering_check", 304 build_setting_default = False, 305) 306 307config_setting( 308 name = "layering_check_enabled", 309 flag_values = {":layering_check": "True"}, 310) 311 312builtin_module_map( 313 name = "builtin_module_map", 314 include_directories = select({ 315 "@platforms//os:linux": [ 316 "@llvm_toolchain//:include-x86_64-unknown-linux-gnu-c++-v1", 317 "@llvm_toolchain//:include-c++-v1", 318 "@llvm_toolchain//:lib-clang-include", 319 "@linux_sysroot//:usr-include-x86_64-linux-gnu", 320 "@linux_sysroot//:usr-include-arm-linux-gnueabihf", 321 "@linux_sysroot//:usr-include", 322 ], 323 "@platforms//os:macos": [ 324 "@llvm_toolchain_macos//:include-x86_64-unknown-linux-gnu-c++-v1", 325 "@llvm_toolchain_macos//:include-c++-v1", 326 "@llvm_toolchain_macos//:lib-clang-include", 327 "@macos_sysroot//:usr-include", 328 "@macos_sysroot//:CoreFoundation.framework-Headers", 329 "@macos_sysroot//:IOKit.framework-Headers", 330 "@macos_sysroot//:Security.framework-Headers", 331 ], 332 "//conditions:default": [], 333 }), 334) 335 336alias( 337 name = "sysroot_root", 338 actual = select({ 339 "@platforms//os:linux": "@linux_sysroot//:sysroot", 340 "@platforms//os:macos": "@macos_sysroot//:sysroot", 341 "//conditions:default": "//pw_build:empty_cc_library", 342 }), 343) 344 345cc_toolchain( 346 name = "host_toolchain", 347 args = select({ 348 "@platforms//os:linux": [ 349 ":linux_link_libs", 350 ":no_pie_for_go_flags", 351 "@linux_sysroot//:sysroot", 352 ], 353 "@platforms//os:macos": [ 354 ":macos_link_libs", 355 ":libtool_darwin_flags", 356 "@macos_sysroot//:sysroot", 357 ], 358 "//conditions:default": [], 359 }) + [ 360 ":thread_safety_warnings", 361 ":link_with_lld", 362 "//pw_toolchain/cc/args:debugging", 363 "//pw_toolchain/cc/args:reduced_size", 364 "//pw_toolchain/cc/args:no_canonical_prefixes", 365 "//pw_toolchain/cc/args:no_rtti", 366 "//pw_toolchain/cc/args:wno_register", 367 "//pw_toolchain/cc/args:wnon_virtual_dtor", 368 "//pw_toolchain/cc/args:common_warnings", 369 "//pw_toolchain/cc/args:color_diagnostics", 370 # Must go after the general warnings that are enabled. 371 ":silence_cgo_warnings", 372 ] + select({ 373 "//pw_build:kythe": [":no_unknown_warning_option"], 374 "//conditions:default": [], 375 }), 376 enabled_features = [ 377 "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", 378 ":supports_pic", 379 ":module_maps", 380 ":rules_go_unsupported_feature", 381 ":rules_rust_unsupported_feature", 382 "//pw_toolchain/cc/capability:compiler_is_clang", 383 "//pw_toolchain/cc/capability:linker_is_clang", 384 ] + select({ 385 ":asan_enabled": [":asan_feature"], 386 "//conditions:default": [], 387 }) + select({ 388 ":ubsan_enabled": [":ubsan_feature"], 389 "//conditions:default": [], 390 }) + select({ 391 ":tsan_enabled": [":tsan_feature"], 392 "//conditions:default": [], 393 }) + select({ 394 "//pw_toolchain/cc:c++17_enabled": ["//pw_toolchain/cc/args:c++17_feature"], 395 "//conditions:default": [], 396 }) + select({ 397 "//pw_toolchain/cc:c++20_enabled": ["//pw_toolchain/cc/args:c++20_feature"], 398 "//conditions:default": [], 399 }) + select({ 400 ":fuzztest_enabled": [":fuzztest_feature"], 401 "//conditions:default": [], 402 }), 403 known_features = [ 404 "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", 405 ":layering_check_feature", 406 ":module_maps", 407 ":use_module_maps", 408 ":asan_feature", 409 ":ubsan_feature", 410 ":tsan_feature", 411 ":verbose_compiler_output", 412 ":rules_rust_unsupported_feature", 413 ":supports_pic", 414 "//pw_toolchain/cc/args:c++17_feature", 415 "//pw_toolchain/cc/args:c++20_feature", 416 "//pw_toolchain/cc/capability:compiler_is_clang", 417 "//pw_toolchain/cc/capability:linker_is_clang", 418 ], 419 # TODO: https://pwbug.dev/219091175 - Remove this select (always set this to 420 # builtin_module_map) once all Pigweed downstream projects are on Bazel 8. 421 module_map = select({ 422 ":layering_check_enabled": ":builtin_module_map", 423 "//conditions:default": None, 424 }), 425 tool_map = select({ 426 "@platforms//os:macos": "@llvm_toolchain_macos//:all_tools", 427 "//conditions:default": "@llvm_toolchain//:all_tools", 428 }), 429) 430 431toolchain( 432 name = "host_cc_toolchain_linux", 433 exec_compatible_with = [ 434 "@platforms//os:linux", 435 ], 436 target_compatible_with = [ 437 "@platforms//os:linux", 438 ], 439 toolchain = ":host_toolchain", 440 toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", 441) 442 443toolchain( 444 name = "host_cc_toolchain_macos", 445 exec_compatible_with = [ 446 "@platforms//os:macos", 447 ], 448 target_compatible_with = [ 449 "@platforms//os:macos", 450 ], 451 toolchain = ":host_toolchain", 452 toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", 453) 454