1# Copyright 2019 The Bazel Authors. All rights reserved. 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"""A Starlark cc_toolchain configuration rule""" 16 17load( 18 "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", 19 "action_config", 20 "feature", 21 "feature_set", 22 "flag_group", 23 "flag_set", 24 "tool", 25 "tool_path", 26 "variable_with_value", 27 "with_feature_set", 28) 29load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") 30 31def layering_check_features(compiler): 32 if compiler != "clang": 33 return [] 34 return [ 35 feature( 36 name = "use_module_maps", 37 requires = [feature_set(features = ["module_maps"])], 38 flag_sets = [ 39 flag_set( 40 actions = [ 41 ACTION_NAMES.c_compile, 42 ACTION_NAMES.cpp_compile, 43 ACTION_NAMES.cpp_header_parsing, 44 ACTION_NAMES.cpp_module_compile, 45 ], 46 flag_groups = [ 47 flag_group( 48 flags = [ 49 "-fmodule-name=%{module_name}", 50 "-fmodule-map-file=%{module_map_file}", 51 ], 52 ), 53 ], 54 ), 55 ], 56 ), 57 58 # Tell blaze we support module maps in general, so they will be generated 59 # for all c/c++ rules. 60 # Note: not all C++ rules support module maps; thus, do not imply this 61 # feature from other features - instead, require it. 62 feature(name = "module_maps", enabled = True), 63 feature( 64 name = "layering_check", 65 implies = ["use_module_maps"], 66 flag_sets = [ 67 flag_set( 68 actions = [ 69 ACTION_NAMES.c_compile, 70 ACTION_NAMES.cpp_compile, 71 ACTION_NAMES.cpp_header_parsing, 72 ACTION_NAMES.cpp_module_compile, 73 ], 74 flag_groups = [ 75 flag_group(flags = [ 76 "-fmodules-strict-decluse", 77 "-Wprivate-header", 78 ]), 79 flag_group( 80 iterate_over = "dependent_module_map_files", 81 flags = [ 82 "-fmodule-map-file=%{dependent_module_map_files}", 83 ], 84 ), 85 ], 86 ), 87 ], 88 ), 89 ] 90 91all_compile_actions = [ 92 ACTION_NAMES.c_compile, 93 ACTION_NAMES.cpp_compile, 94 ACTION_NAMES.linkstamp_compile, 95 ACTION_NAMES.assemble, 96 ACTION_NAMES.preprocess_assemble, 97 ACTION_NAMES.cpp_header_parsing, 98 ACTION_NAMES.cpp_module_compile, 99 ACTION_NAMES.cpp_module_codegen, 100 ACTION_NAMES.clif_match, 101 ACTION_NAMES.lto_backend, 102] 103 104all_cpp_compile_actions = [ 105 ACTION_NAMES.cpp_compile, 106 ACTION_NAMES.linkstamp_compile, 107 ACTION_NAMES.cpp_header_parsing, 108 ACTION_NAMES.cpp_module_compile, 109 ACTION_NAMES.cpp_module_codegen, 110 ACTION_NAMES.clif_match, 111] 112 113preprocessor_compile_actions = [ 114 ACTION_NAMES.c_compile, 115 ACTION_NAMES.cpp_compile, 116 ACTION_NAMES.linkstamp_compile, 117 ACTION_NAMES.preprocess_assemble, 118 ACTION_NAMES.cpp_header_parsing, 119 ACTION_NAMES.cpp_module_compile, 120 ACTION_NAMES.clif_match, 121] 122 123codegen_compile_actions = [ 124 ACTION_NAMES.c_compile, 125 ACTION_NAMES.cpp_compile, 126 ACTION_NAMES.linkstamp_compile, 127 ACTION_NAMES.assemble, 128 ACTION_NAMES.preprocess_assemble, 129 ACTION_NAMES.cpp_module_codegen, 130 ACTION_NAMES.lto_backend, 131] 132 133all_link_actions = [ 134 ACTION_NAMES.cpp_link_executable, 135 ACTION_NAMES.cpp_link_dynamic_library, 136 ACTION_NAMES.cpp_link_nodeps_dynamic_library, 137] 138 139lto_index_actions = [ 140 ACTION_NAMES.lto_index_for_executable, 141 ACTION_NAMES.lto_index_for_dynamic_library, 142 ACTION_NAMES.lto_index_for_nodeps_dynamic_library, 143] 144 145def _impl(ctx): 146 tool_paths = [ 147 tool_path(name = name, path = path) 148 for name, path in ctx.attr.tool_paths.items() 149 ] 150 action_configs = [] 151 152 llvm_cov_action = action_config( 153 action_name = ACTION_NAMES.llvm_cov, 154 tools = [ 155 tool( 156 path = ctx.attr.tool_paths["llvm-cov"], 157 ), 158 ], 159 ) 160 161 action_configs.append(llvm_cov_action) 162 163 supports_pic_feature = feature( 164 name = "supports_pic", 165 enabled = True, 166 ) 167 supports_start_end_lib_feature = feature( 168 name = "supports_start_end_lib", 169 enabled = True, 170 ) 171 172 default_compile_flags_feature = feature( 173 name = "default_compile_flags", 174 enabled = True, 175 flag_sets = [ 176 flag_set( 177 actions = all_compile_actions, 178 flag_groups = [ 179 flag_group( 180 # Security hardening requires optimization. 181 # We need to undef it as some distributions now have it enabled by default. 182 flags = ["-U_FORTIFY_SOURCE"], 183 ), 184 ], 185 with_features = [ 186 with_feature_set( 187 not_features = ["thin_lto"], 188 ), 189 ], 190 ), 191 flag_set( 192 actions = all_compile_actions, 193 flag_groups = ([ 194 flag_group( 195 flags = ctx.attr.compile_flags, 196 ), 197 ] if ctx.attr.compile_flags else []), 198 ), 199 flag_set( 200 actions = all_compile_actions, 201 flag_groups = ([ 202 flag_group( 203 flags = ctx.attr.dbg_compile_flags, 204 ), 205 ] if ctx.attr.dbg_compile_flags else []), 206 with_features = [with_feature_set(features = ["dbg"])], 207 ), 208 flag_set( 209 actions = all_compile_actions, 210 flag_groups = ([ 211 flag_group( 212 flags = ctx.attr.opt_compile_flags, 213 ), 214 ] if ctx.attr.opt_compile_flags else []), 215 with_features = [with_feature_set(features = ["opt"])], 216 ), 217 flag_set( 218 actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend], 219 flag_groups = ([ 220 flag_group( 221 flags = ctx.attr.cxx_flags, 222 ), 223 ] if ctx.attr.cxx_flags else []), 224 ), 225 ], 226 ) 227 228 default_link_flags_feature = feature( 229 name = "default_link_flags", 230 enabled = True, 231 flag_sets = [ 232 flag_set( 233 actions = all_link_actions + lto_index_actions, 234 flag_groups = ([ 235 flag_group( 236 flags = ctx.attr.link_flags, 237 ), 238 ] if ctx.attr.link_flags else []), 239 ), 240 flag_set( 241 actions = all_link_actions + lto_index_actions, 242 flag_groups = ([ 243 flag_group( 244 flags = ctx.attr.opt_link_flags, 245 ), 246 ] if ctx.attr.opt_link_flags else []), 247 with_features = [with_feature_set(features = ["opt"])], 248 ), 249 ], 250 ) 251 252 dbg_feature = feature(name = "dbg") 253 254 opt_feature = feature(name = "opt") 255 256 sysroot_feature = feature( 257 name = "sysroot", 258 enabled = True, 259 flag_sets = [ 260 flag_set( 261 actions = [ 262 ACTION_NAMES.preprocess_assemble, 263 ACTION_NAMES.linkstamp_compile, 264 ACTION_NAMES.c_compile, 265 ACTION_NAMES.cpp_compile, 266 ACTION_NAMES.cpp_header_parsing, 267 ACTION_NAMES.cpp_module_compile, 268 ACTION_NAMES.cpp_module_codegen, 269 ACTION_NAMES.lto_backend, 270 ACTION_NAMES.clif_match, 271 ] + all_link_actions + lto_index_actions, 272 flag_groups = [ 273 flag_group( 274 flags = ["--sysroot=%{sysroot}"], 275 expand_if_available = "sysroot", 276 ), 277 ], 278 ), 279 ], 280 ) 281 282 fdo_optimize_feature = feature( 283 name = "fdo_optimize", 284 flag_sets = [ 285 flag_set( 286 actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], 287 flag_groups = [ 288 flag_group( 289 flags = [ 290 "-fprofile-use=%{fdo_profile_path}", 291 "-fprofile-correction", 292 ], 293 expand_if_available = "fdo_profile_path", 294 ), 295 ], 296 ), 297 ], 298 provides = ["profile"], 299 ) 300 301 supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) 302 303 user_compile_flags_feature = feature( 304 name = "user_compile_flags", 305 enabled = True, 306 flag_sets = [ 307 flag_set( 308 actions = all_compile_actions, 309 flag_groups = [ 310 flag_group( 311 flags = ["%{user_compile_flags}"], 312 iterate_over = "user_compile_flags", 313 expand_if_available = "user_compile_flags", 314 ), 315 ], 316 ), 317 ], 318 ) 319 320 unfiltered_compile_flags_feature = feature( 321 name = "unfiltered_compile_flags", 322 enabled = True, 323 flag_sets = [ 324 flag_set( 325 actions = all_compile_actions, 326 flag_groups = ([ 327 flag_group( 328 flags = ctx.attr.unfiltered_compile_flags, 329 ), 330 ] if ctx.attr.unfiltered_compile_flags else []), 331 ), 332 ], 333 ) 334 335 library_search_directories_feature = feature( 336 name = "library_search_directories", 337 flag_sets = [ 338 flag_set( 339 actions = all_link_actions + lto_index_actions, 340 flag_groups = [ 341 flag_group( 342 flags = ["-L%{library_search_directories}"], 343 iterate_over = "library_search_directories", 344 expand_if_available = "library_search_directories", 345 ), 346 ], 347 ), 348 ], 349 ) 350 351 static_libgcc_feature = feature( 352 name = "static_libgcc", 353 enabled = True, 354 flag_sets = [ 355 flag_set( 356 actions = [ 357 ACTION_NAMES.cpp_link_executable, 358 ACTION_NAMES.cpp_link_dynamic_library, 359 ACTION_NAMES.lto_index_for_executable, 360 ACTION_NAMES.lto_index_for_dynamic_library, 361 ], 362 flag_groups = [flag_group(flags = ["-static-libgcc"])], 363 with_features = [ 364 with_feature_set(features = ["static_link_cpp_runtimes"]), 365 ], 366 ), 367 ], 368 ) 369 370 pic_feature = feature( 371 name = "pic", 372 enabled = True, 373 flag_sets = [ 374 flag_set( 375 actions = [ 376 ACTION_NAMES.assemble, 377 ACTION_NAMES.preprocess_assemble, 378 ACTION_NAMES.linkstamp_compile, 379 ACTION_NAMES.c_compile, 380 ACTION_NAMES.cpp_compile, 381 ACTION_NAMES.cpp_module_codegen, 382 ACTION_NAMES.cpp_module_compile, 383 ], 384 flag_groups = [ 385 flag_group(flags = ["-fPIC"], expand_if_available = "pic"), 386 ], 387 ), 388 ], 389 ) 390 391 per_object_debug_info_feature = feature( 392 name = "per_object_debug_info", 393 flag_sets = [ 394 flag_set( 395 actions = [ 396 ACTION_NAMES.assemble, 397 ACTION_NAMES.preprocess_assemble, 398 ACTION_NAMES.c_compile, 399 ACTION_NAMES.cpp_compile, 400 ACTION_NAMES.cpp_module_codegen, 401 ], 402 flag_groups = [ 403 flag_group( 404 flags = ["-gsplit-dwarf", "-g"], 405 expand_if_available = "per_object_debug_info_file", 406 ), 407 ], 408 ), 409 ], 410 ) 411 412 preprocessor_defines_feature = feature( 413 name = "preprocessor_defines", 414 enabled = True, 415 flag_sets = [ 416 flag_set( 417 actions = [ 418 ACTION_NAMES.preprocess_assemble, 419 ACTION_NAMES.linkstamp_compile, 420 ACTION_NAMES.c_compile, 421 ACTION_NAMES.cpp_compile, 422 ACTION_NAMES.cpp_header_parsing, 423 ACTION_NAMES.cpp_module_compile, 424 ACTION_NAMES.clif_match, 425 ], 426 flag_groups = [ 427 flag_group( 428 flags = ["-D%{preprocessor_defines}"], 429 iterate_over = "preprocessor_defines", 430 ), 431 ], 432 ), 433 ], 434 ) 435 436 cs_fdo_optimize_feature = feature( 437 name = "cs_fdo_optimize", 438 flag_sets = [ 439 flag_set( 440 actions = [ACTION_NAMES.lto_backend], 441 flag_groups = [ 442 flag_group( 443 flags = [ 444 "-fprofile-use=%{fdo_profile_path}", 445 "-Wno-profile-instr-unprofiled", 446 "-Wno-profile-instr-out-of-date", 447 "-fprofile-correction", 448 ], 449 expand_if_available = "fdo_profile_path", 450 ), 451 ], 452 ), 453 ], 454 provides = ["csprofile"], 455 ) 456 457 autofdo_feature = feature( 458 name = "autofdo", 459 flag_sets = [ 460 flag_set( 461 actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], 462 flag_groups = [ 463 flag_group( 464 flags = [ 465 "-fauto-profile=%{fdo_profile_path}", 466 "-fprofile-correction", 467 ], 468 expand_if_available = "fdo_profile_path", 469 ), 470 ], 471 ), 472 ], 473 provides = ["profile"], 474 ) 475 476 runtime_library_search_directories_feature = feature( 477 name = "runtime_library_search_directories", 478 flag_sets = [ 479 flag_set( 480 actions = all_link_actions + lto_index_actions, 481 flag_groups = [ 482 flag_group( 483 iterate_over = "runtime_library_search_directories", 484 flag_groups = [ 485 flag_group( 486 flags = [ 487 "-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}", 488 ], 489 expand_if_true = "is_cc_test", 490 ), 491 flag_group( 492 flags = [ 493 "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", 494 ], 495 expand_if_false = "is_cc_test", 496 ), 497 ], 498 expand_if_available = 499 "runtime_library_search_directories", 500 ), 501 ], 502 with_features = [ 503 with_feature_set(features = ["static_link_cpp_runtimes"]), 504 ], 505 ), 506 flag_set( 507 actions = all_link_actions + lto_index_actions, 508 flag_groups = [ 509 flag_group( 510 iterate_over = "runtime_library_search_directories", 511 flag_groups = [ 512 flag_group( 513 flags = [ 514 "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", 515 ], 516 ), 517 ], 518 expand_if_available = 519 "runtime_library_search_directories", 520 ), 521 ], 522 with_features = [ 523 with_feature_set( 524 not_features = ["static_link_cpp_runtimes"], 525 ), 526 ], 527 ), 528 ], 529 ) 530 531 fission_support_feature = feature( 532 name = "fission_support", 533 flag_sets = [ 534 flag_set( 535 actions = all_link_actions + lto_index_actions, 536 flag_groups = [ 537 flag_group( 538 flags = ["-Wl,--gdb-index"], 539 expand_if_available = "is_using_fission", 540 ), 541 ], 542 ), 543 ], 544 ) 545 546 shared_flag_feature = feature( 547 name = "shared_flag", 548 flag_sets = [ 549 flag_set( 550 actions = [ 551 ACTION_NAMES.cpp_link_dynamic_library, 552 ACTION_NAMES.cpp_link_nodeps_dynamic_library, 553 ACTION_NAMES.lto_index_for_dynamic_library, 554 ACTION_NAMES.lto_index_for_nodeps_dynamic_library, 555 ], 556 flag_groups = [flag_group(flags = ["-shared"])], 557 ), 558 ], 559 ) 560 561 random_seed_feature = feature( 562 name = "random_seed", 563 enabled = True, 564 flag_sets = [ 565 flag_set( 566 actions = [ 567 ACTION_NAMES.c_compile, 568 ACTION_NAMES.cpp_compile, 569 ACTION_NAMES.cpp_module_codegen, 570 ACTION_NAMES.cpp_module_compile, 571 ], 572 flag_groups = [ 573 flag_group( 574 flags = ["-frandom-seed=%{output_file}"], 575 expand_if_available = "output_file", 576 ), 577 ], 578 ), 579 ], 580 ) 581 582 includes_feature = feature( 583 name = "includes", 584 enabled = True, 585 flag_sets = [ 586 flag_set( 587 actions = [ 588 ACTION_NAMES.preprocess_assemble, 589 ACTION_NAMES.linkstamp_compile, 590 ACTION_NAMES.c_compile, 591 ACTION_NAMES.cpp_compile, 592 ACTION_NAMES.cpp_header_parsing, 593 ACTION_NAMES.cpp_module_compile, 594 ACTION_NAMES.clif_match, 595 ACTION_NAMES.objc_compile, 596 ACTION_NAMES.objcpp_compile, 597 ], 598 flag_groups = [ 599 flag_group( 600 flags = ["-include", "%{includes}"], 601 iterate_over = "includes", 602 expand_if_available = "includes", 603 ), 604 ], 605 ), 606 ], 607 ) 608 609 fdo_instrument_feature = feature( 610 name = "fdo_instrument", 611 flag_sets = [ 612 flag_set( 613 actions = [ 614 ACTION_NAMES.c_compile, 615 ACTION_NAMES.cpp_compile, 616 ] + all_link_actions + lto_index_actions, 617 flag_groups = [ 618 flag_group( 619 flags = [ 620 "-fprofile-generate=%{fdo_instrument_path}", 621 "-fno-data-sections", 622 ], 623 expand_if_available = "fdo_instrument_path", 624 ), 625 ], 626 ), 627 ], 628 provides = ["profile"], 629 ) 630 631 cs_fdo_instrument_feature = feature( 632 name = "cs_fdo_instrument", 633 flag_sets = [ 634 flag_set( 635 actions = [ 636 ACTION_NAMES.c_compile, 637 ACTION_NAMES.cpp_compile, 638 ACTION_NAMES.lto_backend, 639 ] + all_link_actions + lto_index_actions, 640 flag_groups = [ 641 flag_group( 642 flags = [ 643 "-fcs-profile-generate=%{cs_fdo_instrument_path}", 644 ], 645 expand_if_available = "cs_fdo_instrument_path", 646 ), 647 ], 648 ), 649 ], 650 provides = ["csprofile"], 651 ) 652 653 include_paths_feature = feature( 654 name = "include_paths", 655 enabled = True, 656 flag_sets = [ 657 flag_set( 658 actions = [ 659 ACTION_NAMES.preprocess_assemble, 660 ACTION_NAMES.linkstamp_compile, 661 ACTION_NAMES.c_compile, 662 ACTION_NAMES.cpp_compile, 663 ACTION_NAMES.cpp_header_parsing, 664 ACTION_NAMES.cpp_module_compile, 665 ACTION_NAMES.clif_match, 666 ACTION_NAMES.objc_compile, 667 ACTION_NAMES.objcpp_compile, 668 ], 669 flag_groups = [ 670 flag_group( 671 flags = ["-iquote", "%{quote_include_paths}"], 672 iterate_over = "quote_include_paths", 673 ), 674 flag_group( 675 flags = ["-I%{include_paths}"], 676 iterate_over = "include_paths", 677 ), 678 flag_group( 679 flags = ["-isystem", "%{system_include_paths}"], 680 iterate_over = "system_include_paths", 681 ), 682 ], 683 ), 684 ], 685 ) 686 687 external_include_paths_feature = feature( 688 name = "external_include_paths", 689 flag_sets = [ 690 flag_set( 691 actions = [ 692 ACTION_NAMES.preprocess_assemble, 693 ACTION_NAMES.linkstamp_compile, 694 ACTION_NAMES.c_compile, 695 ACTION_NAMES.cpp_compile, 696 ACTION_NAMES.cpp_header_parsing, 697 ACTION_NAMES.cpp_module_compile, 698 ACTION_NAMES.clif_match, 699 ACTION_NAMES.objc_compile, 700 ACTION_NAMES.objcpp_compile, 701 ], 702 flag_groups = [ 703 flag_group( 704 flags = ["-isystem", "%{external_include_paths}"], 705 iterate_over = "external_include_paths", 706 expand_if_available = "external_include_paths", 707 ), 708 ], 709 ), 710 ], 711 ) 712 713 symbol_counts_feature = feature( 714 name = "symbol_counts", 715 flag_sets = [ 716 flag_set( 717 actions = all_link_actions + lto_index_actions, 718 flag_groups = [ 719 flag_group( 720 flags = [ 721 "-Wl,--print-symbol-counts=%{symbol_counts_output}", 722 ], 723 expand_if_available = "symbol_counts_output", 724 ), 725 ], 726 ), 727 ], 728 ) 729 730 llvm_coverage_map_format_feature = feature( 731 name = "llvm_coverage_map_format", 732 flag_sets = [ 733 flag_set( 734 actions = [ 735 ACTION_NAMES.preprocess_assemble, 736 ACTION_NAMES.c_compile, 737 ACTION_NAMES.cpp_compile, 738 ACTION_NAMES.cpp_module_compile, 739 ACTION_NAMES.objc_compile, 740 ACTION_NAMES.objcpp_compile, 741 ], 742 flag_groups = [ 743 flag_group( 744 flags = [ 745 "-fprofile-instr-generate", 746 "-fcoverage-mapping", 747 ], 748 ), 749 ], 750 ), 751 flag_set( 752 actions = all_link_actions + lto_index_actions + [ 753 "objc-executable", 754 "objc++-executable", 755 ], 756 flag_groups = [ 757 flag_group(flags = ["-fprofile-instr-generate"]), 758 ], 759 ), 760 ], 761 requires = [feature_set(features = ["coverage"])], 762 provides = ["profile"], 763 ) 764 765 strip_debug_symbols_feature = feature( 766 name = "strip_debug_symbols", 767 flag_sets = [ 768 flag_set( 769 actions = all_link_actions + lto_index_actions, 770 flag_groups = [ 771 flag_group( 772 flags = ["-Wl,-S"], 773 expand_if_available = "strip_debug_symbols", 774 ), 775 ], 776 ), 777 ], 778 ) 779 780 build_interface_libraries_feature = feature( 781 name = "build_interface_libraries", 782 flag_sets = [ 783 flag_set( 784 actions = [ 785 ACTION_NAMES.cpp_link_dynamic_library, 786 ACTION_NAMES.cpp_link_nodeps_dynamic_library, 787 ACTION_NAMES.lto_index_for_dynamic_library, 788 ACTION_NAMES.lto_index_for_nodeps_dynamic_library, 789 ], 790 flag_groups = [ 791 flag_group( 792 flags = [ 793 "%{generate_interface_library}", 794 "%{interface_library_builder_path}", 795 "%{interface_library_input_path}", 796 "%{interface_library_output_path}", 797 ], 798 expand_if_available = "generate_interface_library", 799 ), 800 ], 801 with_features = [ 802 with_feature_set( 803 features = ["supports_interface_shared_libraries"], 804 ), 805 ], 806 ), 807 ], 808 ) 809 810 libraries_to_link_feature = feature( 811 name = "libraries_to_link", 812 flag_sets = [ 813 flag_set( 814 actions = all_link_actions + lto_index_actions, 815 flag_groups = [ 816 flag_group( 817 iterate_over = "libraries_to_link", 818 flag_groups = [ 819 flag_group( 820 flags = ["-Wl,--start-lib"], 821 expand_if_equal = variable_with_value( 822 name = "libraries_to_link.type", 823 value = "object_file_group", 824 ), 825 ), 826 flag_group( 827 flags = ["-Wl,-whole-archive"], 828 expand_if_true = 829 "libraries_to_link.is_whole_archive", 830 ), 831 flag_group( 832 flags = ["%{libraries_to_link.object_files}"], 833 iterate_over = "libraries_to_link.object_files", 834 expand_if_equal = variable_with_value( 835 name = "libraries_to_link.type", 836 value = "object_file_group", 837 ), 838 ), 839 flag_group( 840 flags = ["%{libraries_to_link.name}"], 841 expand_if_equal = variable_with_value( 842 name = "libraries_to_link.type", 843 value = "object_file", 844 ), 845 ), 846 flag_group( 847 flags = ["%{libraries_to_link.name}"], 848 expand_if_equal = variable_with_value( 849 name = "libraries_to_link.type", 850 value = "interface_library", 851 ), 852 ), 853 flag_group( 854 flags = ["%{libraries_to_link.name}"], 855 expand_if_equal = variable_with_value( 856 name = "libraries_to_link.type", 857 value = "static_library", 858 ), 859 ), 860 flag_group( 861 flags = ["-l%{libraries_to_link.name}"], 862 expand_if_equal = variable_with_value( 863 name = "libraries_to_link.type", 864 value = "dynamic_library", 865 ), 866 ), 867 flag_group( 868 flags = ["-l:%{libraries_to_link.name}"], 869 expand_if_equal = variable_with_value( 870 name = "libraries_to_link.type", 871 value = "versioned_dynamic_library", 872 ), 873 ), 874 flag_group( 875 flags = ["-Wl,-no-whole-archive"], 876 expand_if_true = "libraries_to_link.is_whole_archive", 877 ), 878 flag_group( 879 flags = ["-Wl,--end-lib"], 880 expand_if_equal = variable_with_value( 881 name = "libraries_to_link.type", 882 value = "object_file_group", 883 ), 884 ), 885 ], 886 expand_if_available = "libraries_to_link", 887 ), 888 flag_group( 889 flags = ["-Wl,@%{thinlto_param_file}"], 890 expand_if_true = "thinlto_param_file", 891 ), 892 ], 893 ), 894 ], 895 ) 896 897 user_link_flags_feature = feature( 898 name = "user_link_flags", 899 flag_sets = [ 900 flag_set( 901 actions = all_link_actions + lto_index_actions, 902 flag_groups = [ 903 flag_group( 904 flags = ["%{user_link_flags}"], 905 iterate_over = "user_link_flags", 906 expand_if_available = "user_link_flags", 907 ), 908 ] + ([flag_group(flags = ctx.attr.link_libs)] if ctx.attr.link_libs else []), 909 ), 910 ], 911 ) 912 913 fdo_prefetch_hints_feature = feature( 914 name = "fdo_prefetch_hints", 915 flag_sets = [ 916 flag_set( 917 actions = [ 918 ACTION_NAMES.c_compile, 919 ACTION_NAMES.cpp_compile, 920 ACTION_NAMES.lto_backend, 921 ], 922 flag_groups = [ 923 flag_group( 924 flags = [ 925 "-mllvm", 926 "-prefetch-hints-file=%{fdo_prefetch_hints_path}", 927 ], 928 expand_if_available = "fdo_prefetch_hints_path", 929 ), 930 ], 931 ), 932 ], 933 ) 934 935 linkstamps_feature = feature( 936 name = "linkstamps", 937 flag_sets = [ 938 flag_set( 939 actions = all_link_actions + lto_index_actions, 940 flag_groups = [ 941 flag_group( 942 flags = ["%{linkstamp_paths}"], 943 iterate_over = "linkstamp_paths", 944 expand_if_available = "linkstamp_paths", 945 ), 946 ], 947 ), 948 ], 949 ) 950 951 gcc_coverage_map_format_feature = feature( 952 name = "gcc_coverage_map_format", 953 flag_sets = [ 954 flag_set( 955 actions = [ 956 ACTION_NAMES.preprocess_assemble, 957 ACTION_NAMES.c_compile, 958 ACTION_NAMES.cpp_compile, 959 ACTION_NAMES.cpp_module_compile, 960 ACTION_NAMES.objc_compile, 961 ACTION_NAMES.objcpp_compile, 962 "objc-executable", 963 "objc++-executable", 964 ], 965 flag_groups = [ 966 flag_group( 967 flags = ["-fprofile-arcs", "-ftest-coverage"], 968 expand_if_available = "gcov_gcno_file", 969 ), 970 ], 971 ), 972 flag_set( 973 actions = all_link_actions + lto_index_actions, 974 flag_groups = [flag_group(flags = ["--coverage"])], 975 ), 976 ], 977 requires = [feature_set(features = ["coverage"])], 978 provides = ["profile"], 979 ) 980 981 archiver_flags_feature = feature( 982 name = "archiver_flags", 983 flag_sets = [ 984 flag_set( 985 actions = [ACTION_NAMES.cpp_link_static_library], 986 flag_groups = [ 987 flag_group(flags = ["rcsD"]), 988 flag_group( 989 flags = ["%{output_execpath}"], 990 expand_if_available = "output_execpath", 991 ), 992 ], 993 ), 994 flag_set( 995 actions = [ACTION_NAMES.cpp_link_static_library], 996 flag_groups = [ 997 flag_group( 998 iterate_over = "libraries_to_link", 999 flag_groups = [ 1000 flag_group( 1001 flags = ["%{libraries_to_link.name}"], 1002 expand_if_equal = variable_with_value( 1003 name = "libraries_to_link.type", 1004 value = "object_file", 1005 ), 1006 ), 1007 flag_group( 1008 flags = ["%{libraries_to_link.object_files}"], 1009 iterate_over = "libraries_to_link.object_files", 1010 expand_if_equal = variable_with_value( 1011 name = "libraries_to_link.type", 1012 value = "object_file_group", 1013 ), 1014 ), 1015 ], 1016 expand_if_available = "libraries_to_link", 1017 ), 1018 ], 1019 ), 1020 ], 1021 ) 1022 1023 force_pic_flags_feature = feature( 1024 name = "force_pic_flags", 1025 flag_sets = [ 1026 flag_set( 1027 actions = [ 1028 ACTION_NAMES.cpp_link_executable, 1029 ACTION_NAMES.lto_index_for_executable, 1030 ], 1031 flag_groups = [ 1032 flag_group( 1033 flags = ["-pie"], 1034 expand_if_available = "force_pic", 1035 ), 1036 ], 1037 ), 1038 ], 1039 ) 1040 1041 dependency_file_feature = feature( 1042 name = "dependency_file", 1043 enabled = True, 1044 flag_sets = [ 1045 flag_set( 1046 actions = [ 1047 ACTION_NAMES.assemble, 1048 ACTION_NAMES.preprocess_assemble, 1049 ACTION_NAMES.c_compile, 1050 ACTION_NAMES.cpp_compile, 1051 ACTION_NAMES.cpp_module_compile, 1052 ACTION_NAMES.objc_compile, 1053 ACTION_NAMES.objcpp_compile, 1054 ACTION_NAMES.cpp_header_parsing, 1055 ACTION_NAMES.clif_match, 1056 ], 1057 flag_groups = [ 1058 flag_group( 1059 flags = ["-MD", "-MF", "%{dependency_file}"], 1060 expand_if_available = "dependency_file", 1061 ), 1062 ], 1063 ), 1064 ], 1065 ) 1066 1067 serialized_diagnostics_file_feature = feature( 1068 name = "serialized_diagnostics_file", 1069 flag_sets = [ 1070 flag_set( 1071 actions = [ 1072 ACTION_NAMES.assemble, 1073 ACTION_NAMES.preprocess_assemble, 1074 ACTION_NAMES.c_compile, 1075 ACTION_NAMES.cpp_compile, 1076 ACTION_NAMES.cpp_module_compile, 1077 ACTION_NAMES.objc_compile, 1078 ACTION_NAMES.objcpp_compile, 1079 ACTION_NAMES.cpp_header_parsing, 1080 ACTION_NAMES.clif_match, 1081 ], 1082 flag_groups = [ 1083 flag_group( 1084 flags = ["--serialize-diagnostics", "%{serialized_diagnostics_file}"], 1085 expand_if_available = "serialized_diagnostics_file", 1086 ), 1087 ], 1088 ), 1089 ], 1090 ) 1091 1092 dynamic_library_linker_tool_path = tool_paths 1093 dynamic_library_linker_tool_feature = feature( 1094 name = "dynamic_library_linker_tool", 1095 flag_sets = [ 1096 flag_set( 1097 actions = [ 1098 ACTION_NAMES.cpp_link_dynamic_library, 1099 ACTION_NAMES.cpp_link_nodeps_dynamic_library, 1100 ACTION_NAMES.lto_index_for_dynamic_library, 1101 ACTION_NAMES.lto_index_for_nodeps_dynamic_library, 1102 ], 1103 flag_groups = [ 1104 flag_group( 1105 flags = [" + cppLinkDynamicLibraryToolPath + "], 1106 expand_if_available = "generate_interface_library", 1107 ), 1108 ], 1109 with_features = [ 1110 with_feature_set( 1111 features = ["supports_interface_shared_libraries"], 1112 ), 1113 ], 1114 ), 1115 ], 1116 ) 1117 1118 output_execpath_flags_feature = feature( 1119 name = "output_execpath_flags", 1120 flag_sets = [ 1121 flag_set( 1122 actions = all_link_actions + lto_index_actions, 1123 flag_groups = [ 1124 flag_group( 1125 flags = ["-o", "%{output_execpath}"], 1126 expand_if_available = "output_execpath", 1127 ), 1128 ], 1129 ), 1130 ], 1131 ) 1132 1133 # Note that we also set --coverage for c++-link-nodeps-dynamic-library. The 1134 # generated code contains references to gcov symbols, and the dynamic linker 1135 # can't resolve them unless the library is linked against gcov. 1136 coverage_feature = feature( 1137 name = "coverage", 1138 provides = ["profile"], 1139 flag_sets = [ 1140 flag_set( 1141 actions = [ 1142 ACTION_NAMES.preprocess_assemble, 1143 ACTION_NAMES.c_compile, 1144 ACTION_NAMES.cpp_compile, 1145 ACTION_NAMES.cpp_header_parsing, 1146 ACTION_NAMES.cpp_module_compile, 1147 ], 1148 flag_groups = ([ 1149 flag_group(flags = ctx.attr.coverage_compile_flags), 1150 ] if ctx.attr.coverage_compile_flags else []), 1151 ), 1152 flag_set( 1153 actions = all_link_actions + lto_index_actions, 1154 flag_groups = ([ 1155 flag_group(flags = ctx.attr.coverage_link_flags), 1156 ] if ctx.attr.coverage_link_flags else []), 1157 ), 1158 ], 1159 ) 1160 1161 thinlto_feature = feature( 1162 name = "thin_lto", 1163 flag_sets = [ 1164 flag_set( 1165 actions = [ 1166 ACTION_NAMES.c_compile, 1167 ACTION_NAMES.cpp_compile, 1168 ] + all_link_actions + lto_index_actions, 1169 flag_groups = [ 1170 flag_group(flags = ["-flto=thin"]), 1171 flag_group( 1172 expand_if_available = "lto_indexing_bitcode_file", 1173 flags = [ 1174 "-Xclang", 1175 "-fthin-link-bitcode=%{lto_indexing_bitcode_file}", 1176 ], 1177 ), 1178 ], 1179 ), 1180 flag_set( 1181 actions = [ACTION_NAMES.linkstamp_compile], 1182 flag_groups = [flag_group(flags = ["-DBUILD_LTO_TYPE=thin"])], 1183 ), 1184 flag_set( 1185 actions = lto_index_actions, 1186 flag_groups = [ 1187 flag_group(flags = [ 1188 "-flto=thin", 1189 "-Wl,-plugin-opt,thinlto-index-only%{thinlto_optional_params_file}", 1190 "-Wl,-plugin-opt,thinlto-emit-imports-files", 1191 "-Wl,-plugin-opt,thinlto-prefix-replace=%{thinlto_prefix_replace}", 1192 ]), 1193 flag_group( 1194 expand_if_available = "thinlto_object_suffix_replace", 1195 flags = [ 1196 "-Wl,-plugin-opt,thinlto-object-suffix-replace=%{thinlto_object_suffix_replace}", 1197 ], 1198 ), 1199 flag_group( 1200 expand_if_available = "thinlto_merged_object_file", 1201 flags = [ 1202 "-Wl,-plugin-opt,obj-path=%{thinlto_merged_object_file}", 1203 ], 1204 ), 1205 ], 1206 ), 1207 flag_set( 1208 actions = [ACTION_NAMES.lto_backend], 1209 flag_groups = [ 1210 flag_group(flags = [ 1211 "-c", 1212 "-fthinlto-index=%{thinlto_index}", 1213 "-o", 1214 "%{thinlto_output_object_file}", 1215 "-x", 1216 "ir", 1217 "%{thinlto_input_bitcode_file}", 1218 ]), 1219 ], 1220 ), 1221 ], 1222 ) 1223 1224 is_linux = ctx.attr.target_libc != "macosx" 1225 1226 # TODO(#8303): Mac crosstool should also declare every feature. 1227 if is_linux: 1228 features = [ 1229 dependency_file_feature, 1230 serialized_diagnostics_file_feature, 1231 random_seed_feature, 1232 pic_feature, 1233 per_object_debug_info_feature, 1234 preprocessor_defines_feature, 1235 includes_feature, 1236 include_paths_feature, 1237 external_include_paths_feature, 1238 fdo_instrument_feature, 1239 cs_fdo_instrument_feature, 1240 cs_fdo_optimize_feature, 1241 thinlto_feature, 1242 fdo_prefetch_hints_feature, 1243 autofdo_feature, 1244 build_interface_libraries_feature, 1245 dynamic_library_linker_tool_feature, 1246 symbol_counts_feature, 1247 shared_flag_feature, 1248 linkstamps_feature, 1249 output_execpath_flags_feature, 1250 runtime_library_search_directories_feature, 1251 library_search_directories_feature, 1252 archiver_flags_feature, 1253 force_pic_flags_feature, 1254 fission_support_feature, 1255 strip_debug_symbols_feature, 1256 coverage_feature, 1257 supports_pic_feature, 1258 ] + ( 1259 [ 1260 supports_start_end_lib_feature, 1261 ] if ctx.attr.supports_start_end_lib else [] 1262 ) + [ 1263 default_compile_flags_feature, 1264 default_link_flags_feature, 1265 libraries_to_link_feature, 1266 user_link_flags_feature, 1267 static_libgcc_feature, 1268 fdo_optimize_feature, 1269 supports_dynamic_linker_feature, 1270 dbg_feature, 1271 opt_feature, 1272 user_compile_flags_feature, 1273 sysroot_feature, 1274 unfiltered_compile_flags_feature, 1275 ] + layering_check_features(ctx.attr.compiler) 1276 else: 1277 features = [ 1278 supports_pic_feature, 1279 ] + ( 1280 [ 1281 supports_start_end_lib_feature, 1282 ] if ctx.attr.supports_start_end_lib else [] 1283 ) + [ 1284 coverage_feature, 1285 default_compile_flags_feature, 1286 default_link_flags_feature, 1287 user_link_flags_feature, 1288 fdo_optimize_feature, 1289 supports_dynamic_linker_feature, 1290 dbg_feature, 1291 opt_feature, 1292 user_compile_flags_feature, 1293 sysroot_feature, 1294 unfiltered_compile_flags_feature, 1295 ] + layering_check_features(ctx.attr.compiler) 1296 1297 return cc_common.create_cc_toolchain_config_info( 1298 ctx = ctx, 1299 features = features, 1300 action_configs = action_configs, 1301 cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories, 1302 toolchain_identifier = ctx.attr.toolchain_identifier, 1303 host_system_name = ctx.attr.host_system_name, 1304 target_system_name = ctx.attr.target_system_name, 1305 target_cpu = ctx.attr.cpu, 1306 target_libc = ctx.attr.target_libc, 1307 compiler = ctx.attr.compiler, 1308 abi_version = ctx.attr.abi_version, 1309 abi_libc_version = ctx.attr.abi_libc_version, 1310 tool_paths = tool_paths, 1311 builtin_sysroot = ctx.attr.builtin_sysroot, 1312 ) 1313 1314cc_toolchain_config = rule( 1315 implementation = _impl, 1316 attrs = { 1317 "cpu": attr.string(mandatory = True), 1318 "compiler": attr.string(mandatory = True), 1319 "toolchain_identifier": attr.string(mandatory = True), 1320 "host_system_name": attr.string(mandatory = True), 1321 "target_system_name": attr.string(mandatory = True), 1322 "target_libc": attr.string(mandatory = True), 1323 "abi_version": attr.string(mandatory = True), 1324 "abi_libc_version": attr.string(mandatory = True), 1325 "cxx_builtin_include_directories": attr.string_list(), 1326 "tool_paths": attr.string_dict(), 1327 "compile_flags": attr.string_list(), 1328 "dbg_compile_flags": attr.string_list(), 1329 "opt_compile_flags": attr.string_list(), 1330 "cxx_flags": attr.string_list(), 1331 "link_flags": attr.string_list(), 1332 "link_libs": attr.string_list(), 1333 "opt_link_flags": attr.string_list(), 1334 "unfiltered_compile_flags": attr.string_list(), 1335 "coverage_compile_flags": attr.string_list(), 1336 "coverage_link_flags": attr.string_list(), 1337 "supports_start_end_lib": attr.bool(), 1338 "builtin_sysroot": attr.string(), 1339 }, 1340 provides = [CcToolchainConfigInfo], 1341) 1342