• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 for Windows"""
16
17load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
18load(
19    "@rules_cc//cc:cc_toolchain_config_lib.bzl",
20    "action_config",
21    "artifact_name_pattern",
22    "env_entry",
23    "env_set",
24    "feature",
25    "feature_set",
26    "flag_group",
27    "flag_set",
28    "tool",
29    "tool_path",
30    "variable_with_value",
31    "with_feature_set",
32)
33
34all_compile_actions = [
35    ACTION_NAMES.c_compile,
36    ACTION_NAMES.cpp_compile,
37    ACTION_NAMES.linkstamp_compile,
38    ACTION_NAMES.assemble,
39    ACTION_NAMES.preprocess_assemble,
40    ACTION_NAMES.cpp_header_parsing,
41    ACTION_NAMES.cpp_module_compile,
42    ACTION_NAMES.cpp_module_codegen,
43    ACTION_NAMES.clif_match,
44    ACTION_NAMES.lto_backend,
45]
46
47all_cpp_compile_actions = [
48    ACTION_NAMES.cpp_compile,
49    ACTION_NAMES.linkstamp_compile,
50    ACTION_NAMES.cpp_header_parsing,
51    ACTION_NAMES.cpp_module_compile,
52    ACTION_NAMES.cpp_module_codegen,
53    ACTION_NAMES.clif_match,
54]
55
56preprocessor_compile_actions = [
57    ACTION_NAMES.c_compile,
58    ACTION_NAMES.cpp_compile,
59    ACTION_NAMES.linkstamp_compile,
60    ACTION_NAMES.preprocess_assemble,
61    ACTION_NAMES.cpp_header_parsing,
62    ACTION_NAMES.cpp_module_compile,
63    ACTION_NAMES.clif_match,
64]
65
66codegen_compile_actions = [
67    ACTION_NAMES.c_compile,
68    ACTION_NAMES.cpp_compile,
69    ACTION_NAMES.linkstamp_compile,
70    ACTION_NAMES.assemble,
71    ACTION_NAMES.preprocess_assemble,
72    ACTION_NAMES.cpp_module_codegen,
73    ACTION_NAMES.lto_backend,
74]
75
76all_link_actions = [
77    ACTION_NAMES.cpp_link_executable,
78    ACTION_NAMES.cpp_link_dynamic_library,
79    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
80]
81
82def _use_msvc_toolchain(ctx):
83    return ctx.attr.cpu == "x64_windows" and (ctx.attr.compiler == "msvc-cl" or ctx.attr.compiler == "clang-cl")
84
85def _impl(ctx):
86    if _use_msvc_toolchain(ctx):
87        artifact_name_patterns = [
88            artifact_name_pattern(
89                category_name = "object_file",
90                prefix = "",
91                extension = ".obj",
92            ),
93            artifact_name_pattern(
94                category_name = "static_library",
95                prefix = "",
96                extension = ".lib",
97            ),
98            artifact_name_pattern(
99                category_name = "alwayslink_static_library",
100                prefix = "",
101                extension = ".lo.lib",
102            ),
103            artifact_name_pattern(
104                category_name = "executable",
105                prefix = "",
106                extension = ".exe",
107            ),
108            artifact_name_pattern(
109                category_name = "dynamic_library",
110                prefix = "",
111                extension = ".dll",
112            ),
113            artifact_name_pattern(
114                category_name = "interface_library",
115                prefix = "",
116                extension = ".if.lib",
117            ),
118        ]
119    else:
120        artifact_name_patterns = [
121            artifact_name_pattern(
122                category_name = "executable",
123                prefix = "",
124                extension = ".exe",
125            ),
126        ]
127
128    if _use_msvc_toolchain(ctx):
129        cpp_link_nodeps_dynamic_library_action = action_config(
130            action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library,
131            implies = [
132                "nologo",
133                "shared_flag",
134                "linkstamps",
135                "output_execpath_flags",
136                "input_param_flags",
137                "user_link_flags",
138                "default_link_flags",
139                "linker_subsystem_flag",
140                "linker_param_file",
141                "msvc_env",
142                "no_stripping",
143                "has_configured_linker_path",
144                "def_file",
145            ],
146            tools = [tool(path = ctx.attr.msvc_link_path)],
147        )
148
149        cpp_link_static_library_action = action_config(
150            action_name = ACTION_NAMES.cpp_link_static_library,
151            implies = [
152                "nologo",
153                "archiver_flags",
154                "input_param_flags",
155                "linker_param_file",
156                "msvc_env",
157            ],
158            tools = [tool(path = ctx.attr.msvc_lib_path)],
159        )
160
161        assemble_action = action_config(
162            action_name = ACTION_NAMES.assemble,
163            implies = [
164                "compiler_input_flags",
165                "compiler_output_flags",
166                "nologo",
167                "msvc_env",
168                "sysroot",
169            ],
170            tools = [tool(path = ctx.attr.msvc_ml_path)],
171        )
172
173        preprocess_assemble_action = action_config(
174            action_name = ACTION_NAMES.preprocess_assemble,
175            implies = [
176                "compiler_input_flags",
177                "compiler_output_flags",
178                "nologo",
179                "msvc_env",
180                "sysroot",
181            ],
182            tools = [tool(path = ctx.attr.msvc_ml_path)],
183        )
184
185        c_compile_action = action_config(
186            action_name = ACTION_NAMES.c_compile,
187            implies = [
188                "compiler_input_flags",
189                "compiler_output_flags",
190                "default_compile_flags",
191                "nologo",
192                "msvc_env",
193                "parse_showincludes",
194                "user_compile_flags",
195                "sysroot",
196                "unfiltered_compile_flags",
197            ],
198            tools = [tool(path = ctx.attr.msvc_cl_path)],
199        )
200
201        cpp_compile_action = action_config(
202            action_name = ACTION_NAMES.cpp_compile,
203            implies = [
204                "compiler_input_flags",
205                "compiler_output_flags",
206                "default_compile_flags",
207                "nologo",
208                "msvc_env",
209                "parse_showincludes",
210                "user_compile_flags",
211                "sysroot",
212                "unfiltered_compile_flags",
213            ],
214            tools = [tool(path = ctx.attr.msvc_cl_path)],
215        )
216
217        cpp_link_executable_action = action_config(
218            action_name = ACTION_NAMES.cpp_link_executable,
219            implies = [
220                "nologo",
221                "linkstamps",
222                "output_execpath_flags",
223                "input_param_flags",
224                "user_link_flags",
225                "default_link_flags",
226                "linker_subsystem_flag",
227                "linker_param_file",
228                "msvc_env",
229                "no_stripping",
230            ],
231            tools = [tool(path = ctx.attr.msvc_link_path)],
232        )
233
234        cpp_link_dynamic_library_action = action_config(
235            action_name = ACTION_NAMES.cpp_link_dynamic_library,
236            implies = [
237                "nologo",
238                "shared_flag",
239                "linkstamps",
240                "output_execpath_flags",
241                "input_param_flags",
242                "user_link_flags",
243                "default_link_flags",
244                "linker_subsystem_flag",
245                "linker_param_file",
246                "msvc_env",
247                "no_stripping",
248                "has_configured_linker_path",
249                "def_file",
250            ],
251            tools = [tool(path = ctx.attr.msvc_link_path)],
252        )
253
254        action_configs = [
255            assemble_action,
256            preprocess_assemble_action,
257            c_compile_action,
258            cpp_compile_action,
259            cpp_link_executable_action,
260            cpp_link_dynamic_library_action,
261            cpp_link_nodeps_dynamic_library_action,
262            cpp_link_static_library_action,
263        ]
264    else:
265        action_configs = []
266
267    if _use_msvc_toolchain(ctx):
268        msvc_link_env_feature = feature(
269            name = "msvc_link_env",
270            env_sets = [
271                env_set(
272                    actions = all_link_actions +
273                              [ACTION_NAMES.cpp_link_static_library],
274                    env_entries = [env_entry(key = "LIB", value = ctx.attr.msvc_env_lib)],
275                ),
276            ],
277        )
278
279        shared_flag_feature = feature(
280            name = "shared_flag",
281            flag_sets = [
282                flag_set(
283                    actions = [
284                        ACTION_NAMES.cpp_link_dynamic_library,
285                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
286                    ],
287                    flag_groups = [flag_group(flags = ["/DLL"])],
288                ),
289            ],
290        )
291
292        determinism_feature = feature(
293            name = "determinism",
294            enabled = True,
295            flag_sets = [
296                flag_set(
297                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
298                    flag_groups = [
299                        flag_group(
300                            flags = [
301                                "/wd4117",
302                                "-D__DATE__=\"redacted\"",
303                                "-D__TIMESTAMP__=\"redacted\"",
304                                "-D__TIME__=\"redacted\"",
305                            ] + (["-Wno-builtin-macro-redefined"] if ctx.attr.compiler == "clang-cl" else []),
306                        ),
307                    ],
308                ),
309            ],
310        )
311
312        sysroot_feature = feature(
313            name = "sysroot",
314            flag_sets = [
315                flag_set(
316                    actions = [
317                        ACTION_NAMES.assemble,
318                        ACTION_NAMES.preprocess_assemble,
319                        ACTION_NAMES.c_compile,
320                        ACTION_NAMES.cpp_compile,
321                        ACTION_NAMES.cpp_header_parsing,
322                        ACTION_NAMES.cpp_module_compile,
323                        ACTION_NAMES.cpp_module_codegen,
324                        ACTION_NAMES.cpp_link_executable,
325                        ACTION_NAMES.cpp_link_dynamic_library,
326                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
327                    ],
328                    flag_groups = [
329                        flag_group(
330                            flags = ["--sysroot=%{sysroot}"],
331                            iterate_over = "sysroot",
332                            expand_if_available = "sysroot",
333                        ),
334                    ],
335                ),
336            ],
337        )
338
339        unfiltered_compile_flags_feature = feature(
340            name = "unfiltered_compile_flags",
341            flag_sets = [
342                flag_set(
343                    actions = [
344                        ACTION_NAMES.preprocess_assemble,
345                        ACTION_NAMES.c_compile,
346                        ACTION_NAMES.cpp_compile,
347                        ACTION_NAMES.cpp_header_parsing,
348                        ACTION_NAMES.cpp_module_compile,
349                        ACTION_NAMES.cpp_module_codegen,
350                    ],
351                    flag_groups = [
352                        flag_group(
353                            flags = ["%{unfiltered_compile_flags}"],
354                            iterate_over = "unfiltered_compile_flags",
355                            expand_if_available = "unfiltered_compile_flags",
356                        ),
357                    ],
358                ),
359            ],
360        )
361
362        compiler_param_file_feature = feature(
363            name = "compiler_param_file",
364        )
365
366        copy_dynamic_libraries_to_binary_feature = feature(
367            name = "copy_dynamic_libraries_to_binary",
368        )
369
370        input_param_flags_feature = feature(
371            name = "input_param_flags",
372            flag_sets = [
373                flag_set(
374                    actions = [
375                        ACTION_NAMES.cpp_link_dynamic_library,
376                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
377                    ],
378                    flag_groups = [
379                        flag_group(
380                            flags = ["/IMPLIB:%{interface_library_output_path}"],
381                            expand_if_available = "interface_library_output_path",
382                        ),
383                    ],
384                ),
385                flag_set(
386                    actions = all_link_actions,
387                    flag_groups = [
388                        flag_group(
389                            flags = ["%{libopts}"],
390                            iterate_over = "libopts",
391                            expand_if_available = "libopts",
392                        ),
393                    ],
394                ),
395                flag_set(
396                    actions = all_link_actions +
397                              [ACTION_NAMES.cpp_link_static_library],
398                    flag_groups = [
399                        flag_group(
400                            iterate_over = "libraries_to_link",
401                            flag_groups = [
402                                flag_group(
403                                    iterate_over = "libraries_to_link.object_files",
404                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])],
405                                    expand_if_equal = variable_with_value(
406                                        name = "libraries_to_link.type",
407                                        value = "object_file_group",
408                                    ),
409                                ),
410                                flag_group(
411                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
412                                    expand_if_equal = variable_with_value(
413                                        name = "libraries_to_link.type",
414                                        value = "object_file",
415                                    ),
416                                ),
417                                flag_group(
418                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
419                                    expand_if_equal = variable_with_value(
420                                        name = "libraries_to_link.type",
421                                        value = "interface_library",
422                                    ),
423                                ),
424                                flag_group(
425                                    flag_groups = [
426                                        flag_group(
427                                            flags = ["%{libraries_to_link.name}"],
428                                            expand_if_false = "libraries_to_link.is_whole_archive",
429                                        ),
430                                        flag_group(
431                                            flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"],
432                                            expand_if_true = "libraries_to_link.is_whole_archive",
433                                        ),
434                                    ],
435                                    expand_if_equal = variable_with_value(
436                                        name = "libraries_to_link.type",
437                                        value = "static_library",
438                                    ),
439                                ),
440                            ],
441                            expand_if_available = "libraries_to_link",
442                        ),
443                    ],
444                ),
445            ],
446        )
447
448        fastbuild_feature = feature(
449            name = "fastbuild",
450            flag_sets = [
451                flag_set(
452                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
453                    flag_groups = [flag_group(flags = ["/Od", "/Z7"])],
454                ),
455                flag_set(
456                    actions = all_link_actions,
457                    flag_groups = [
458                        flag_group(
459                            flags = [ctx.attr.fastbuild_mode_debug_flag, "/INCREMENTAL:NO"],
460                        ),
461                    ],
462                ),
463            ],
464            implies = ["generate_pdb_file"],
465        )
466
467        user_compile_flags_feature = feature(
468            name = "user_compile_flags",
469            flag_sets = [
470                flag_set(
471                    actions = [
472                        ACTION_NAMES.preprocess_assemble,
473                        ACTION_NAMES.c_compile,
474                        ACTION_NAMES.cpp_compile,
475                        ACTION_NAMES.cpp_header_parsing,
476                        ACTION_NAMES.cpp_module_compile,
477                        ACTION_NAMES.cpp_module_codegen,
478                    ],
479                    flag_groups = [
480                        flag_group(
481                            flags = ["%{user_compile_flags}"],
482                            iterate_over = "user_compile_flags",
483                            expand_if_available = "user_compile_flags",
484                        ),
485                    ],
486                ),
487            ],
488        )
489
490        archiver_flags_feature = feature(
491            name = "archiver_flags",
492            flag_sets = [
493                flag_set(
494                    actions = [ACTION_NAMES.cpp_link_static_library],
495                    flag_groups = [
496                        flag_group(
497                            flags = ["/OUT:%{output_execpath}"],
498                            expand_if_available = "output_execpath",
499                        ),
500                        flag_group(
501                            flags = ["/MACHINE:X64"],
502                        ),
503                    ],
504                ),
505            ],
506        )
507
508        default_link_flags_feature = feature(
509            name = "default_link_flags",
510            enabled = True,
511            flag_sets = [
512                flag_set(
513                    actions = all_link_actions,
514                    flag_groups = [flag_group(flags = ctx.attr.default_link_flags)],
515                ),
516            ],
517        )
518
519        static_link_msvcrt_feature = feature(name = "static_link_msvcrt")
520
521        dynamic_link_msvcrt_debug_feature = feature(
522            name = "dynamic_link_msvcrt_debug",
523            flag_sets = [
524                flag_set(
525                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
526                    flag_groups = [flag_group(flags = ["/MDd"])],
527                ),
528                flag_set(
529                    actions = all_link_actions,
530                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])],
531                ),
532            ],
533            requires = [feature_set(features = ["dbg"])],
534        )
535
536        dbg_feature = feature(
537            name = "dbg",
538            flag_sets = [
539                flag_set(
540                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
541                    flag_groups = [flag_group(flags = ["/Od", "/Z7"])],
542                ),
543                flag_set(
544                    actions = all_link_actions,
545                    flag_groups = [
546                        flag_group(
547                            flags = [ctx.attr.dbg_mode_debug_flag, "/INCREMENTAL:NO"],
548                        ),
549                    ],
550                ),
551            ],
552            implies = ["generate_pdb_file"],
553        )
554
555        opt_feature = feature(
556            name = "opt",
557            flag_sets = [
558                flag_set(
559                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
560                    flag_groups = [flag_group(flags = ["/O2"])],
561                ),
562            ],
563            implies = ["frame_pointer"],
564        )
565
566        supports_interface_shared_libraries_feature = feature(
567            name = "supports_interface_shared_libraries",
568            enabled = True,
569        )
570
571        user_link_flags_feature = feature(
572            name = "user_link_flags",
573            flag_sets = [
574                flag_set(
575                    actions = all_link_actions,
576                    flag_groups = [
577                        flag_group(
578                            flags = ["%{user_link_flags}"],
579                            iterate_over = "user_link_flags",
580                            expand_if_available = "user_link_flags",
581                        ),
582                    ],
583                ),
584            ],
585        )
586
587        default_compile_flags_feature = feature(
588            name = "default_compile_flags",
589            enabled = True,
590            flag_sets = [
591                flag_set(
592                    actions = [
593                        ACTION_NAMES.assemble,
594                        ACTION_NAMES.preprocess_assemble,
595                        ACTION_NAMES.linkstamp_compile,
596                        ACTION_NAMES.c_compile,
597                        ACTION_NAMES.cpp_compile,
598                        ACTION_NAMES.cpp_header_parsing,
599                        ACTION_NAMES.cpp_module_compile,
600                        ACTION_NAMES.cpp_module_codegen,
601                        ACTION_NAMES.lto_backend,
602                        ACTION_NAMES.clif_match,
603                    ],
604                    flag_groups = [
605                        flag_group(
606                            flags = [
607                                "/DCOMPILER_MSVC",
608                                "/DNOMINMAX",
609                                "/D_WIN32_WINNT=0x0601",
610                                "/D_CRT_SECURE_NO_DEPRECATE",
611                                "/D_CRT_SECURE_NO_WARNINGS",
612                                "/bigobj",
613                                "/Zm500",
614                                "/EHsc",
615                                "/wd4351",
616                                "/wd4291",
617                                "/wd4250",
618                                "/wd4996",
619                            ],
620                        ),
621                    ],
622                ),
623            ],
624        )
625
626        msvc_compile_env_feature = feature(
627            name = "msvc_compile_env",
628            env_sets = [
629                env_set(
630                    actions = [
631                        ACTION_NAMES.c_compile,
632                        ACTION_NAMES.cpp_compile,
633                        ACTION_NAMES.cpp_module_compile,
634                        ACTION_NAMES.cpp_module_codegen,
635                        ACTION_NAMES.cpp_header_parsing,
636                        ACTION_NAMES.assemble,
637                        ACTION_NAMES.preprocess_assemble,
638                    ],
639                    env_entries = [env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include)],
640                ),
641            ],
642        )
643
644        preprocessor_defines_feature = feature(
645            name = "preprocessor_defines",
646            enabled = True,
647            flag_sets = [
648                flag_set(
649                    actions = [
650                        ACTION_NAMES.assemble,
651                        ACTION_NAMES.preprocess_assemble,
652                        ACTION_NAMES.c_compile,
653                        ACTION_NAMES.cpp_compile,
654                        ACTION_NAMES.cpp_header_parsing,
655                        ACTION_NAMES.cpp_module_compile,
656                    ],
657                    flag_groups = [
658                        flag_group(
659                            flags = ["/D%{preprocessor_defines}"],
660                            iterate_over = "preprocessor_defines",
661                        ),
662                    ],
663                ),
664            ],
665        )
666
667        generate_pdb_file_feature = feature(
668            name = "generate_pdb_file",
669        )
670
671        output_execpath_flags_feature = feature(
672            name = "output_execpath_flags",
673            flag_sets = [
674                flag_set(
675                    actions = all_link_actions,
676                    flag_groups = [
677                        flag_group(
678                            flags = ["/OUT:%{output_execpath}"],
679                            expand_if_available = "output_execpath",
680                        ),
681                    ],
682                ),
683            ],
684        )
685
686        dynamic_link_msvcrt_no_debug_feature = feature(
687            name = "dynamic_link_msvcrt_no_debug",
688            flag_sets = [
689                flag_set(
690                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
691                    flag_groups = [flag_group(flags = ["/MD"])],
692                ),
693                flag_set(
694                    actions = all_link_actions,
695                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])],
696                ),
697            ],
698            requires = [
699                feature_set(features = ["fastbuild"]),
700                feature_set(features = ["opt"]),
701            ],
702        )
703
704        disable_assertions_feature = feature(
705            name = "disable_assertions",
706            enabled = True,
707            flag_sets = [
708                flag_set(
709                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
710                    flag_groups = [flag_group(flags = ["/DNDEBUG"])],
711                    with_features = [with_feature_set(features = ["opt"])],
712                ),
713            ],
714        )
715
716        has_configured_linker_path_feature = feature(name = "has_configured_linker_path")
717
718        supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True)
719
720        no_stripping_feature = feature(name = "no_stripping")
721
722        linker_param_file_feature = feature(
723            name = "linker_param_file",
724            flag_sets = [
725                flag_set(
726                    actions = all_link_actions +
727                              [ACTION_NAMES.cpp_link_static_library],
728                    flag_groups = [
729                        flag_group(
730                            flags = ["@%{linker_param_file}"],
731                            expand_if_available = "linker_param_file",
732                        ),
733                    ],
734                ),
735            ],
736        )
737
738        ignore_noisy_warnings_feature = feature(
739            name = "ignore_noisy_warnings",
740            enabled = True,
741            flag_sets = [
742                flag_set(
743                    actions = [ACTION_NAMES.cpp_link_static_library],
744                    flag_groups = [flag_group(flags = ["/ignore:4221"])],
745                ),
746            ],
747        )
748
749        no_legacy_features_feature = feature(name = "no_legacy_features")
750
751        parse_showincludes_feature = feature(
752            name = "parse_showincludes",
753            flag_sets = [
754                flag_set(
755                    actions = [
756                        ACTION_NAMES.preprocess_assemble,
757                        ACTION_NAMES.c_compile,
758                        ACTION_NAMES.cpp_compile,
759                        ACTION_NAMES.cpp_module_compile,
760                        ACTION_NAMES.cpp_header_parsing,
761                    ],
762                    flag_groups = [flag_group(flags = ["/showIncludes"])],
763                ),
764            ],
765        )
766
767        static_link_msvcrt_no_debug_feature = feature(
768            name = "static_link_msvcrt_no_debug",
769            flag_sets = [
770                flag_set(
771                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
772                    flag_groups = [flag_group(flags = ["/MT"])],
773                ),
774                flag_set(
775                    actions = all_link_actions,
776                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])],
777                ),
778            ],
779            requires = [
780                feature_set(features = ["fastbuild"]),
781                feature_set(features = ["opt"]),
782            ],
783        )
784
785        treat_warnings_as_errors_feature = feature(
786            name = "treat_warnings_as_errors",
787            flag_sets = [
788                flag_set(
789                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
790                    flag_groups = [flag_group(flags = ["/WX"])],
791                ),
792            ],
793        )
794
795        windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols")
796
797        no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols")
798
799        include_paths_feature = feature(
800            name = "include_paths",
801            enabled = True,
802            flag_sets = [
803                flag_set(
804                    actions = [
805                        ACTION_NAMES.assemble,
806                        ACTION_NAMES.preprocess_assemble,
807                        ACTION_NAMES.c_compile,
808                        ACTION_NAMES.cpp_compile,
809                        ACTION_NAMES.cpp_header_parsing,
810                        ACTION_NAMES.cpp_module_compile,
811                    ],
812                    flag_groups = [
813                        flag_group(
814                            flags = ["/I%{quote_include_paths}"],
815                            iterate_over = "quote_include_paths",
816                        ),
817                        flag_group(
818                            flags = ["/I%{include_paths}"],
819                            iterate_over = "include_paths",
820                        ),
821                        flag_group(
822                            flags = ["/I%{system_include_paths}"],
823                            iterate_over = "system_include_paths",
824                        ),
825                    ],
826                ),
827            ],
828        )
829
830        linkstamps_feature = feature(
831            name = "linkstamps",
832            flag_sets = [
833                flag_set(
834                    actions = all_link_actions,
835                    flag_groups = [
836                        flag_group(
837                            flags = ["%{linkstamp_paths}"],
838                            iterate_over = "linkstamp_paths",
839                            expand_if_available = "linkstamp_paths",
840                        ),
841                    ],
842                ),
843            ],
844        )
845
846        targets_windows_feature = feature(
847            name = "targets_windows",
848            enabled = True,
849            implies = ["copy_dynamic_libraries_to_binary"],
850        )
851
852        linker_subsystem_flag_feature = feature(
853            name = "linker_subsystem_flag",
854            flag_sets = [
855                flag_set(
856                    actions = all_link_actions,
857                    flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])],
858                ),
859            ],
860        )
861
862        static_link_msvcrt_debug_feature = feature(
863            name = "static_link_msvcrt_debug",
864            flag_sets = [
865                flag_set(
866                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
867                    flag_groups = [flag_group(flags = ["/MTd"])],
868                ),
869                flag_set(
870                    actions = all_link_actions,
871                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])],
872                ),
873            ],
874            requires = [feature_set(features = ["dbg"])],
875        )
876
877        frame_pointer_feature = feature(
878            name = "frame_pointer",
879            flag_sets = [
880                flag_set(
881                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
882                    flag_groups = [flag_group(flags = ["/Oy-"])],
883                ),
884            ],
885        )
886
887        compiler_output_flags_feature = feature(
888            name = "compiler_output_flags",
889            flag_sets = [
890                flag_set(
891                    actions = [ACTION_NAMES.assemble],
892                    flag_groups = [
893                        flag_group(
894                            flag_groups = [
895                                flag_group(
896                                    flags = ["/Fo%{output_file}", "/Zi"],
897                                    expand_if_available = "output_file",
898                                    expand_if_not_available = "output_assembly_file",
899                                ),
900                            ],
901                            expand_if_not_available = "output_preprocess_file",
902                        ),
903                    ],
904                ),
905                flag_set(
906                    actions = [
907                        ACTION_NAMES.preprocess_assemble,
908                        ACTION_NAMES.c_compile,
909                        ACTION_NAMES.cpp_compile,
910                        ACTION_NAMES.cpp_header_parsing,
911                        ACTION_NAMES.cpp_module_compile,
912                        ACTION_NAMES.cpp_module_codegen,
913                    ],
914                    flag_groups = [
915                        flag_group(
916                            flag_groups = [
917                                flag_group(
918                                    flags = ["/Fo%{output_file}"],
919                                    expand_if_not_available = "output_preprocess_file",
920                                ),
921                            ],
922                            expand_if_available = "output_file",
923                            expand_if_not_available = "output_assembly_file",
924                        ),
925                        flag_group(
926                            flag_groups = [
927                                flag_group(
928                                    flags = ["/Fa%{output_file}"],
929                                    expand_if_available = "output_assembly_file",
930                                ),
931                            ],
932                            expand_if_available = "output_file",
933                        ),
934                        flag_group(
935                            flag_groups = [
936                                flag_group(
937                                    flags = ["/P", "/Fi%{output_file}"],
938                                    expand_if_available = "output_preprocess_file",
939                                ),
940                            ],
941                            expand_if_available = "output_file",
942                        ),
943                    ],
944                ),
945            ],
946        )
947
948        nologo_feature = feature(
949            name = "nologo",
950            flag_sets = [
951                flag_set(
952                    actions = [
953                        ACTION_NAMES.c_compile,
954                        ACTION_NAMES.cpp_compile,
955                        ACTION_NAMES.cpp_module_compile,
956                        ACTION_NAMES.cpp_module_codegen,
957                        ACTION_NAMES.cpp_header_parsing,
958                        ACTION_NAMES.assemble,
959                        ACTION_NAMES.preprocess_assemble,
960                        ACTION_NAMES.cpp_link_executable,
961                        ACTION_NAMES.cpp_link_dynamic_library,
962                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
963                        ACTION_NAMES.cpp_link_static_library,
964                    ],
965                    flag_groups = [flag_group(flags = ["/nologo"])],
966                ),
967            ],
968        )
969
970        smaller_binary_feature = feature(
971            name = "smaller_binary",
972            enabled = True,
973            flag_sets = [
974                flag_set(
975                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
976                    flag_groups = [flag_group(flags = ["/Gy", "/Gw"])],
977                    with_features = [with_feature_set(features = ["opt"])],
978                ),
979                flag_set(
980                    actions = all_link_actions,
981                    flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])],
982                    with_features = [with_feature_set(features = ["opt"])],
983                ),
984            ],
985        )
986
987        compiler_input_flags_feature = feature(
988            name = "compiler_input_flags",
989            flag_sets = [
990                flag_set(
991                    actions = [
992                        ACTION_NAMES.assemble,
993                        ACTION_NAMES.preprocess_assemble,
994                        ACTION_NAMES.c_compile,
995                        ACTION_NAMES.cpp_compile,
996                        ACTION_NAMES.cpp_header_parsing,
997                        ACTION_NAMES.cpp_module_compile,
998                        ACTION_NAMES.cpp_module_codegen,
999                    ],
1000                    flag_groups = [
1001                        flag_group(
1002                            flags = ["/c", "%{source_file}"],
1003                            expand_if_available = "source_file",
1004                        ),
1005                    ],
1006                ),
1007            ],
1008        )
1009
1010        def_file_feature = feature(
1011            name = "def_file",
1012            flag_sets = [
1013                flag_set(
1014                    actions = all_link_actions,
1015                    flag_groups = [
1016                        flag_group(
1017                            flags = ["/DEF:%{def_file_path}", "/ignore:4070"],
1018                            expand_if_available = "def_file_path",
1019                        ),
1020                    ],
1021                ),
1022            ],
1023        )
1024
1025        msvc_env_feature = feature(
1026            name = "msvc_env",
1027            env_sets = [
1028                env_set(
1029                    actions = [
1030                        ACTION_NAMES.c_compile,
1031                        ACTION_NAMES.cpp_compile,
1032                        ACTION_NAMES.cpp_module_compile,
1033                        ACTION_NAMES.cpp_module_codegen,
1034                        ACTION_NAMES.cpp_header_parsing,
1035                        ACTION_NAMES.assemble,
1036                        ACTION_NAMES.preprocess_assemble,
1037                        ACTION_NAMES.cpp_link_executable,
1038                        ACTION_NAMES.cpp_link_dynamic_library,
1039                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1040                        ACTION_NAMES.cpp_link_static_library,
1041                    ],
1042                    env_entries = [
1043                        env_entry(key = "PATH", value = ctx.attr.msvc_env_path),
1044                        env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp),
1045                        env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp),
1046                    ],
1047                ),
1048            ],
1049            implies = ["msvc_compile_env", "msvc_link_env"],
1050        )
1051        features = [
1052            no_legacy_features_feature,
1053            nologo_feature,
1054            has_configured_linker_path_feature,
1055            no_stripping_feature,
1056            targets_windows_feature,
1057            copy_dynamic_libraries_to_binary_feature,
1058            default_compile_flags_feature,
1059            msvc_env_feature,
1060            msvc_compile_env_feature,
1061            msvc_link_env_feature,
1062            include_paths_feature,
1063            preprocessor_defines_feature,
1064            parse_showincludes_feature,
1065            generate_pdb_file_feature,
1066            shared_flag_feature,
1067            linkstamps_feature,
1068            output_execpath_flags_feature,
1069            archiver_flags_feature,
1070            input_param_flags_feature,
1071            linker_subsystem_flag_feature,
1072            user_link_flags_feature,
1073            default_link_flags_feature,
1074            linker_param_file_feature,
1075            static_link_msvcrt_feature,
1076            static_link_msvcrt_no_debug_feature,
1077            dynamic_link_msvcrt_no_debug_feature,
1078            static_link_msvcrt_debug_feature,
1079            dynamic_link_msvcrt_debug_feature,
1080            dbg_feature,
1081            fastbuild_feature,
1082            opt_feature,
1083            frame_pointer_feature,
1084            disable_assertions_feature,
1085            determinism_feature,
1086            treat_warnings_as_errors_feature,
1087            smaller_binary_feature,
1088            ignore_noisy_warnings_feature,
1089            user_compile_flags_feature,
1090            sysroot_feature,
1091            unfiltered_compile_flags_feature,
1092            compiler_param_file_feature,
1093            compiler_output_flags_feature,
1094            compiler_input_flags_feature,
1095            def_file_feature,
1096            windows_export_all_symbols_feature,
1097            no_windows_export_all_symbols_feature,
1098            supports_dynamic_linker_feature,
1099            supports_interface_shared_libraries_feature,
1100        ]
1101    else:
1102        targets_windows_feature = feature(
1103            name = "targets_windows",
1104            implies = ["copy_dynamic_libraries_to_binary"],
1105            enabled = True,
1106        )
1107
1108        copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary")
1109
1110        gcc_env_feature = feature(
1111            name = "gcc_env",
1112            enabled = True,
1113            env_sets = [
1114                env_set(
1115                    actions = [
1116                        ACTION_NAMES.c_compile,
1117                        ACTION_NAMES.cpp_compile,
1118                        ACTION_NAMES.cpp_module_compile,
1119                        ACTION_NAMES.cpp_module_codegen,
1120                        ACTION_NAMES.cpp_header_parsing,
1121                        ACTION_NAMES.assemble,
1122                        ACTION_NAMES.preprocess_assemble,
1123                        ACTION_NAMES.cpp_link_executable,
1124                        ACTION_NAMES.cpp_link_dynamic_library,
1125                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1126                        ACTION_NAMES.cpp_link_static_library,
1127                    ],
1128                    env_entries = [
1129                        env_entry(key = "PATH", value = ctx.attr.tool_bin_path),
1130                    ],
1131                ),
1132            ],
1133        )
1134
1135        default_compile_flags_feature = feature(
1136            name = "default_compile_flags",
1137            enabled = True,
1138            flag_sets = [
1139                flag_set(
1140                    actions = [
1141                        ACTION_NAMES.linkstamp_compile,
1142                        ACTION_NAMES.cpp_compile,
1143                        ACTION_NAMES.cpp_header_parsing,
1144                        ACTION_NAMES.cpp_module_compile,
1145                        ACTION_NAMES.cpp_module_codegen,
1146                        ACTION_NAMES.lto_backend,
1147                        ACTION_NAMES.clif_match,
1148                    ],
1149                    flag_groups = [flag_group(flags = ["-std=gnu++0x"])],
1150                ),
1151            ],
1152        )
1153
1154        default_link_flags_feature = feature(
1155            name = "default_link_flags",
1156            enabled = True,
1157            flag_sets = [
1158                flag_set(
1159                    actions = all_link_actions,
1160                    flag_groups = [flag_group(flags = ["-lstdc++"])],
1161                ),
1162            ],
1163        )
1164
1165        supports_dynamic_linker_feature = feature(
1166            name = "supports_dynamic_linker",
1167            enabled = True,
1168        )
1169
1170        if ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc":
1171            compiler_param_file_feature = feature(
1172                name = "compiler_param_file",
1173            )
1174
1175            features = [
1176                targets_windows_feature,
1177                copy_dynamic_libraries_to_binary_feature,
1178                gcc_env_feature,
1179                default_compile_flags_feature,
1180                compiler_param_file_feature,
1181                default_link_flags_feature,
1182                supports_dynamic_linker_feature,
1183            ]
1184        else:
1185            supports_pic_feature = feature(
1186                name = "supports_pic",
1187                enabled = True,
1188            )
1189            supports_start_end_lib_feature = feature(
1190                name = "supports_start_end_lib",
1191                enabled = True,
1192            )
1193
1194            dbg_feature = feature(name = "dbg")
1195
1196            opt_feature = feature(name = "opt")
1197
1198            sysroot_feature = feature(
1199                name = "sysroot",
1200                enabled = True,
1201                flag_sets = [
1202                    flag_set(
1203                        actions = [
1204                            ACTION_NAMES.preprocess_assemble,
1205                            ACTION_NAMES.linkstamp_compile,
1206                            ACTION_NAMES.c_compile,
1207                            ACTION_NAMES.cpp_compile,
1208                            ACTION_NAMES.cpp_header_parsing,
1209                            ACTION_NAMES.cpp_module_compile,
1210                            ACTION_NAMES.cpp_module_codegen,
1211                            ACTION_NAMES.lto_backend,
1212                            ACTION_NAMES.clif_match,
1213                            ACTION_NAMES.cpp_link_executable,
1214                            ACTION_NAMES.cpp_link_dynamic_library,
1215                            ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1216                        ],
1217                        flag_groups = [
1218                            flag_group(
1219                                flags = ["--sysroot=%{sysroot}"],
1220                                expand_if_available = "sysroot",
1221                            ),
1222                        ],
1223                    ),
1224                ],
1225            )
1226
1227            fdo_optimize_feature = feature(
1228                name = "fdo_optimize",
1229                flag_sets = [
1230                    flag_set(
1231                        actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1232                        flag_groups = [
1233                            flag_group(
1234                                flags = [
1235                                    "-fprofile-use=%{fdo_profile_path}",
1236                                    "-fprofile-correction",
1237                                ],
1238                                expand_if_available = "fdo_profile_path",
1239                            ),
1240                        ],
1241                    ),
1242                ],
1243                provides = ["profile"],
1244            )
1245
1246            user_compile_flags_feature = feature(
1247                name = "user_compile_flags",
1248                enabled = True,
1249                flag_sets = [
1250                    flag_set(
1251                        actions = [
1252                            ACTION_NAMES.assemble,
1253                            ACTION_NAMES.preprocess_assemble,
1254                            ACTION_NAMES.linkstamp_compile,
1255                            ACTION_NAMES.c_compile,
1256                            ACTION_NAMES.cpp_compile,
1257                            ACTION_NAMES.cpp_header_parsing,
1258                            ACTION_NAMES.cpp_module_compile,
1259                            ACTION_NAMES.cpp_module_codegen,
1260                            ACTION_NAMES.lto_backend,
1261                            ACTION_NAMES.clif_match,
1262                        ],
1263                        flag_groups = [
1264                            flag_group(
1265                                flags = ["%{user_compile_flags}"],
1266                                iterate_over = "user_compile_flags",
1267                                expand_if_available = "user_compile_flags",
1268                            ),
1269                        ],
1270                    ),
1271                ],
1272            )
1273
1274            features = [
1275                targets_windows_feature,
1276                copy_dynamic_libraries_to_binary_feature,
1277                gcc_env_feature,
1278                supports_pic_feature,
1279                supports_start_end_lib_feature,
1280                default_compile_flags_feature,
1281                default_link_flags_feature,
1282                fdo_optimize_feature,
1283                supports_dynamic_linker_feature,
1284                dbg_feature,
1285                opt_feature,
1286                user_compile_flags_feature,
1287                sysroot_feature,
1288            ]
1289
1290    tool_paths = [
1291        tool_path(name = name, path = path)
1292        for name, path in ctx.attr.tool_paths.items()
1293    ]
1294
1295    return cc_common.create_cc_toolchain_config_info(
1296        ctx = ctx,
1297        features = features,
1298        action_configs = action_configs,
1299        artifact_name_patterns = artifact_name_patterns,
1300        cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories,
1301        toolchain_identifier = ctx.attr.toolchain_identifier,
1302        host_system_name = ctx.attr.host_system_name,
1303        target_system_name = ctx.attr.target_system_name,
1304        target_cpu = ctx.attr.cpu,
1305        target_libc = ctx.attr.target_libc,
1306        compiler = ctx.attr.compiler,
1307        abi_version = ctx.attr.abi_version,
1308        abi_libc_version = ctx.attr.abi_libc_version,
1309        tool_paths = tool_paths,
1310    )
1311
1312cc_toolchain_config = rule(
1313    implementation = _impl,
1314    attrs = {
1315        "abi_libc_version": attr.string(),
1316        "abi_version": attr.string(),
1317        "compiler": attr.string(),
1318        "cpu": attr.string(mandatory = True),
1319        "cxx_builtin_include_directories": attr.string_list(),
1320        "dbg_mode_debug_flag": attr.string(),
1321        "default_link_flags": attr.string_list(default = []),
1322        "fastbuild_mode_debug_flag": attr.string(),
1323        "host_system_name": attr.string(),
1324        "msvc_cl_path": attr.string(default = "vc_installation_error.bat"),
1325        "msvc_env_include": attr.string(default = "msvc_not_found"),
1326        "msvc_env_lib": attr.string(default = "msvc_not_found"),
1327        "msvc_env_path": attr.string(default = "msvc_not_found"),
1328        "msvc_env_tmp": attr.string(default = "msvc_not_found"),
1329        "msvc_lib_path": attr.string(default = "vc_installation_error.bat"),
1330        "msvc_link_path": attr.string(default = "vc_installation_error.bat"),
1331        "msvc_ml_path": attr.string(default = "vc_installation_error.bat"),
1332        "target_libc": attr.string(),
1333        "target_system_name": attr.string(),
1334        "tool_bin_path": attr.string(default = "not_found"),
1335        "tool_paths": attr.string_dict(),
1336        "toolchain_identifier": attr.string(),
1337    },
1338    provides = [CcToolchainConfigInfo],
1339)
1340