• 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    "flag_group",
26    "flag_set",
27    "make_variable",
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.cpp_module_deps_scanning,
44    ACTION_NAMES.cpp20_module_compile,
45    ACTION_NAMES.cpp20_module_codegen,
46    ACTION_NAMES.clif_match,
47    ACTION_NAMES.lto_backend,
48]
49
50all_cpp_compile_actions = [
51    ACTION_NAMES.cpp_compile,
52    ACTION_NAMES.linkstamp_compile,
53    ACTION_NAMES.cpp_header_parsing,
54    ACTION_NAMES.cpp_module_compile,
55    ACTION_NAMES.cpp_module_codegen,
56    ACTION_NAMES.cpp_module_deps_scanning,
57    ACTION_NAMES.cpp20_module_compile,
58    ACTION_NAMES.cpp20_module_codegen,
59    ACTION_NAMES.clif_match,
60]
61
62preprocessor_compile_actions = [
63    ACTION_NAMES.c_compile,
64    ACTION_NAMES.cpp_compile,
65    ACTION_NAMES.linkstamp_compile,
66    ACTION_NAMES.preprocess_assemble,
67    ACTION_NAMES.cpp_header_parsing,
68    ACTION_NAMES.cpp_module_compile,
69    ACTION_NAMES.cpp_module_deps_scanning,
70    ACTION_NAMES.cpp20_module_compile,
71    ACTION_NAMES.clif_match,
72]
73
74codegen_compile_actions = [
75    ACTION_NAMES.c_compile,
76    ACTION_NAMES.cpp_compile,
77    ACTION_NAMES.linkstamp_compile,
78    ACTION_NAMES.assemble,
79    ACTION_NAMES.preprocess_assemble,
80    ACTION_NAMES.cpp_module_codegen,
81    ACTION_NAMES.cpp20_module_codegen,
82    ACTION_NAMES.lto_backend,
83]
84
85all_link_actions = [
86    ACTION_NAMES.cpp_link_executable,
87    ACTION_NAMES.cpp_link_dynamic_library,
88    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
89]
90
91def _use_msvc_toolchain(ctx):
92    return ctx.attr.cpu in ["x64_windows", "arm64_windows"] and (ctx.attr.compiler == "msvc-cl" or ctx.attr.compiler == "clang-cl")
93
94def _impl(ctx):
95    if _use_msvc_toolchain(ctx):
96        artifact_name_patterns = [
97            artifact_name_pattern(
98                category_name = "object_file",
99                prefix = "",
100                extension = ".obj",
101            ),
102            artifact_name_pattern(
103                category_name = "static_library",
104                prefix = "",
105                extension = ".lib",
106            ),
107            artifact_name_pattern(
108                category_name = "alwayslink_static_library",
109                prefix = "",
110                extension = ".lo.lib",
111            ),
112            artifact_name_pattern(
113                category_name = "executable",
114                prefix = "",
115                extension = ".exe",
116            ),
117            artifact_name_pattern(
118                category_name = "dynamic_library",
119                prefix = "",
120                extension = ".dll",
121            ),
122            artifact_name_pattern(
123                category_name = "interface_library",
124                prefix = "",
125                extension = ".if.lib",
126            ),
127        ]
128    else:
129        artifact_name_patterns = [
130            artifact_name_pattern(
131                category_name = "executable",
132                prefix = "",
133                extension = ".exe",
134            ),
135        ]
136
137    if _use_msvc_toolchain(ctx):
138        cpp_link_nodeps_dynamic_library_action = action_config(
139            action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library,
140            implies = [
141                "nologo",
142                "shared_flag",
143                "linkstamps",
144                "output_execpath_flags",
145                "input_param_flags",
146                "user_link_flags",
147                "linker_subsystem_flag",
148                "linker_param_file",
149                "msvc_env",
150                "no_stripping",
151                "has_configured_linker_path",
152                "def_file",
153            ],
154            tools = [tool(path = ctx.attr.msvc_link_path)],
155        )
156
157        cpp_link_static_library_action = action_config(
158            action_name = ACTION_NAMES.cpp_link_static_library,
159            implies = [
160                "nologo",
161                "archiver_flags",
162                "input_param_flags",
163                "linker_param_file",
164                "msvc_env",
165            ],
166            tools = [tool(path = ctx.attr.msvc_lib_path)],
167        )
168
169        assemble_action = action_config(
170            action_name = ACTION_NAMES.assemble,
171            implies = [
172                "compiler_input_flags",
173                "compiler_output_flags",
174                "nologo",
175                "msvc_env",
176                "sysroot",
177            ],
178            tools = [tool(path = ctx.attr.msvc_ml_path)],
179        )
180
181        preprocess_assemble_action = action_config(
182            action_name = ACTION_NAMES.preprocess_assemble,
183            implies = [
184                "compiler_input_flags",
185                "compiler_output_flags",
186                "nologo",
187                "msvc_env",
188                "sysroot",
189            ],
190            tools = [tool(path = ctx.attr.msvc_ml_path)],
191        )
192
193        c_compile_action = action_config(
194            action_name = ACTION_NAMES.c_compile,
195            implies = [
196                "compiler_input_flags",
197                "compiler_output_flags",
198                "nologo",
199                "msvc_env",
200                "user_compile_flags",
201                "sysroot",
202            ],
203            tools = [tool(path = ctx.attr.msvc_cl_path)],
204        )
205
206        linkstamp_compile_action = action_config(
207            action_name = ACTION_NAMES.linkstamp_compile,
208            implies = [
209                "compiler_input_flags",
210                "compiler_output_flags",
211                "default_compile_flags",
212                "nologo",
213                "msvc_env",
214                "user_compile_flags",
215                "sysroot",
216                "unfiltered_compile_flags",
217            ],
218            tools = [tool(path = ctx.attr.msvc_cl_path)],
219        )
220
221        cpp_compile_action = action_config(
222            action_name = ACTION_NAMES.cpp_compile,
223            implies = [
224                "compiler_input_flags",
225                "compiler_output_flags",
226                "nologo",
227                "msvc_env",
228                "user_compile_flags",
229                "sysroot",
230            ],
231            tools = [tool(path = ctx.attr.msvc_cl_path)],
232        )
233
234        cpp_link_executable_action = action_config(
235            action_name = ACTION_NAMES.cpp_link_executable,
236            implies = [
237                "nologo",
238                "linkstamps",
239                "output_execpath_flags",
240                "input_param_flags",
241                "user_link_flags",
242                "linker_subsystem_flag",
243                "linker_param_file",
244                "msvc_env",
245                "no_stripping",
246            ],
247            tools = [tool(path = ctx.attr.msvc_link_path)],
248        )
249
250        cpp_link_dynamic_library_action = action_config(
251            action_name = ACTION_NAMES.cpp_link_dynamic_library,
252            implies = [
253                "nologo",
254                "shared_flag",
255                "linkstamps",
256                "output_execpath_flags",
257                "input_param_flags",
258                "user_link_flags",
259                "linker_subsystem_flag",
260                "linker_param_file",
261                "msvc_env",
262                "no_stripping",
263                "has_configured_linker_path",
264                "def_file",
265            ],
266            tools = [tool(path = ctx.attr.msvc_link_path)],
267        )
268
269        deps_scanner = "cpp-module-deps-scanner_not_found"
270        if "cpp-module-deps-scanner" in ctx.attr.tool_paths:
271            deps_scanner = ctx.attr.tool_paths["cpp-module-deps-scanner"]
272        cpp_module_scan_deps = action_config(
273            action_name = ACTION_NAMES.cpp_module_deps_scanning,
274            tools = [
275                tool(
276                    path = deps_scanner,
277                ),
278            ],
279            implies = [
280                "compiler_input_flags",
281                "compiler_output_flags",
282                "nologo",
283                "msvc_env",
284                "user_compile_flags",
285                "sysroot",
286            ],
287        )
288
289        cpp20_module_compile = action_config(
290            action_name = ACTION_NAMES.cpp20_module_compile,
291            tools = [
292                tool(
293                    path = ctx.attr.msvc_cl_path,
294                ),
295            ],
296            flag_sets = [
297                flag_set(
298                    flag_groups = [
299                        flag_group(
300                            flags = [
301                                "/TP",
302                                "/interface",
303                            ],
304                        ),
305                    ],
306                ),
307            ],
308            implies = [
309                "compiler_input_flags",
310                "compiler_output_flags",
311                "nologo",
312                "msvc_env",
313                "user_compile_flags",
314                "sysroot",
315            ],
316        )
317
318        cpp20_module_codegen = action_config(
319            action_name = ACTION_NAMES.cpp20_module_codegen,
320            tools = [
321                tool(
322                    path = ctx.attr.msvc_cl_path,
323                ),
324            ],
325            implies = [
326                "compiler_input_flags",
327                "compiler_output_flags",
328                "nologo",
329                "msvc_env",
330                "user_compile_flags",
331                "sysroot",
332            ],
333        )
334        action_configs = [
335            assemble_action,
336            preprocess_assemble_action,
337            c_compile_action,
338            linkstamp_compile_action,
339            cpp_compile_action,
340            cpp_link_executable_action,
341            cpp_link_dynamic_library_action,
342            cpp_link_nodeps_dynamic_library_action,
343            cpp_link_static_library_action,
344            cpp_module_scan_deps,
345            cpp20_module_compile,
346            cpp20_module_codegen,
347        ]
348    else:
349        action_configs = []
350
351    if _use_msvc_toolchain(ctx):
352        msvc_link_env_feature = feature(
353            name = "msvc_link_env",
354            env_sets = [
355                env_set(
356                    actions = all_link_actions +
357                              [ACTION_NAMES.cpp_link_static_library],
358                    env_entries = [env_entry(key = "LIB", value = ctx.attr.msvc_env_lib)],
359                ),
360            ],
361        )
362
363        shared_flag_feature = feature(
364            name = "shared_flag",
365            flag_sets = [
366                flag_set(
367                    actions = [
368                        ACTION_NAMES.cpp_link_dynamic_library,
369                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
370                    ],
371                    flag_groups = [flag_group(flags = ["/DLL"])],
372                ),
373            ],
374        )
375
376        determinism_feature = feature(
377            name = "determinism",
378            enabled = True,
379            flag_sets = [
380                flag_set(
381                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
382                    flag_groups = [
383                        flag_group(
384                            flags = [
385                                "/wd4117",
386                                "-D__DATE__=\"redacted\"",
387                                "-D__TIMESTAMP__=\"redacted\"",
388                                "-D__TIME__=\"redacted\"",
389                            ] + (["-Wno-builtin-macro-redefined"] if ctx.attr.compiler == "clang-cl" else []),
390                        ),
391                    ],
392                ),
393            ],
394        )
395
396        sysroot_feature = feature(
397            name = "sysroot",
398            flag_sets = [
399                flag_set(
400                    actions = [
401                        ACTION_NAMES.assemble,
402                        ACTION_NAMES.preprocess_assemble,
403                        ACTION_NAMES.c_compile,
404                        ACTION_NAMES.linkstamp_compile,
405                        ACTION_NAMES.cpp_compile,
406                        ACTION_NAMES.cpp_header_parsing,
407                        ACTION_NAMES.cpp_module_compile,
408                        ACTION_NAMES.cpp_module_codegen,
409                        ACTION_NAMES.cpp_module_deps_scanning,
410                        ACTION_NAMES.cpp20_module_compile,
411                        ACTION_NAMES.cpp20_module_codegen,
412                        ACTION_NAMES.cpp_link_executable,
413                        ACTION_NAMES.cpp_link_dynamic_library,
414                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
415                    ],
416                    flag_groups = [
417                        flag_group(
418                            flags = ["--sysroot=%{sysroot}"],
419                            iterate_over = "sysroot",
420                            expand_if_available = "sysroot",
421                        ),
422                    ],
423                ),
424            ],
425        )
426
427        unfiltered_compile_flags_feature = feature(
428            name = "unfiltered_compile_flags",
429            enabled = True,
430            flag_sets = [
431                flag_set(
432                    actions = [
433                        ACTION_NAMES.preprocess_assemble,
434                        ACTION_NAMES.c_compile,
435                        ACTION_NAMES.linkstamp_compile,
436                        ACTION_NAMES.cpp_compile,
437                        ACTION_NAMES.cpp_header_parsing,
438                        ACTION_NAMES.cpp_module_compile,
439                        ACTION_NAMES.cpp_module_codegen,
440                        ACTION_NAMES.cpp_module_deps_scanning,
441                        ACTION_NAMES.cpp20_module_compile,
442                        ACTION_NAMES.cpp20_module_codegen,
443                    ],
444                    flag_groups = [
445                        flag_group(
446                            flags = ["%{unfiltered_compile_flags}"],
447                            iterate_over = "unfiltered_compile_flags",
448                            expand_if_available = "unfiltered_compile_flags",
449                        ),
450                    ],
451                ),
452            ],
453        )
454
455        archive_param_file_feature = feature(
456            name = "archive_param_file",
457            enabled = True,
458        )
459
460        compiler_param_file_feature = feature(
461            name = "compiler_param_file",
462            enabled = True,
463        )
464
465        copy_dynamic_libraries_to_binary_feature = feature(
466            name = "copy_dynamic_libraries_to_binary",
467        )
468
469        input_param_flags_feature = feature(
470            name = "input_param_flags",
471            flag_sets = [
472                flag_set(
473                    actions = [
474                        ACTION_NAMES.cpp_link_dynamic_library,
475                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
476                    ],
477                    flag_groups = [
478                        flag_group(
479                            flags = ["/IMPLIB:%{interface_library_output_path}"],
480                            expand_if_available = "interface_library_output_path",
481                        ),
482                    ],
483                ),
484                flag_set(
485                    actions = all_link_actions,
486                    flag_groups = [
487                        flag_group(
488                            flags = ["%{libopts}"],
489                            iterate_over = "libopts",
490                            expand_if_available = "libopts",
491                        ),
492                    ],
493                ),
494                flag_set(
495                    actions = all_link_actions +
496                              [ACTION_NAMES.cpp_link_static_library],
497                    flag_groups = [
498                        flag_group(
499                            iterate_over = "libraries_to_link",
500                            flag_groups = [
501                                flag_group(
502                                    iterate_over = "libraries_to_link.object_files",
503                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])],
504                                    expand_if_equal = variable_with_value(
505                                        name = "libraries_to_link.type",
506                                        value = "object_file_group",
507                                    ),
508                                ),
509                                flag_group(
510                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
511                                    expand_if_equal = variable_with_value(
512                                        name = "libraries_to_link.type",
513                                        value = "object_file",
514                                    ),
515                                ),
516                                flag_group(
517                                    flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
518                                    expand_if_equal = variable_with_value(
519                                        name = "libraries_to_link.type",
520                                        value = "interface_library",
521                                    ),
522                                ),
523                                flag_group(
524                                    flag_groups = [
525                                        flag_group(
526                                            flags = ["%{libraries_to_link.name}"],
527                                            expand_if_false = "libraries_to_link.is_whole_archive",
528                                        ),
529                                        flag_group(
530                                            flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"],
531                                            expand_if_true = "libraries_to_link.is_whole_archive",
532                                        ),
533                                    ],
534                                    expand_if_equal = variable_with_value(
535                                        name = "libraries_to_link.type",
536                                        value = "static_library",
537                                    ),
538                                ),
539                            ],
540                            expand_if_available = "libraries_to_link",
541                        ),
542                    ],
543                ),
544            ],
545        )
546
547        fastbuild_feature = feature(
548            name = "fastbuild",
549            flag_sets = [
550                flag_set(
551                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
552                    flag_groups = [flag_group(flags = ["/Od", "/Z7"])],
553                ),
554                flag_set(
555                    actions = all_link_actions,
556                    flag_groups = [
557                        flag_group(
558                            flags = [ctx.attr.fastbuild_mode_debug_flag, "/INCREMENTAL:NO"],
559                        ),
560                    ],
561                ),
562            ],
563            implies = ["generate_pdb_file"],
564        )
565
566        user_compile_flags_feature = feature(
567            name = "user_compile_flags",
568            flag_sets = [
569                flag_set(
570                    actions = [
571                        ACTION_NAMES.preprocess_assemble,
572                        ACTION_NAMES.c_compile,
573                        ACTION_NAMES.linkstamp_compile,
574                        ACTION_NAMES.cpp_compile,
575                        ACTION_NAMES.cpp_header_parsing,
576                        ACTION_NAMES.cpp_module_compile,
577                        ACTION_NAMES.cpp_module_codegen,
578                        ACTION_NAMES.cpp_module_deps_scanning,
579                        ACTION_NAMES.cpp20_module_compile,
580                        ACTION_NAMES.cpp20_module_codegen,
581                    ],
582                    flag_groups = [
583                        flag_group(
584                            flags = ["%{user_compile_flags}"],
585                            iterate_over = "user_compile_flags",
586                            expand_if_available = "user_compile_flags",
587                        ),
588                    ],
589                ),
590            ],
591        )
592
593        archiver_flags_feature = feature(
594            name = "archiver_flags",
595            flag_sets = [
596                flag_set(
597                    actions = [ACTION_NAMES.cpp_link_static_library],
598                    flag_groups = [
599                        flag_group(
600                            flags = ["/OUT:%{output_execpath}"],
601                            expand_if_available = "output_execpath",
602                        ),
603                        flag_group(
604                            flags = ["%{user_archiver_flags}"],
605                            iterate_over = "user_archiver_flags",
606                            expand_if_available = "user_archiver_flags",
607                        ),
608                        flag_group(
609                            flags = ctx.attr.archiver_flags,
610                        ),
611                    ],
612                ),
613            ],
614        )
615
616        default_link_flags_feature = feature(
617            name = "default_link_flags",
618            enabled = True,
619            flag_sets = [
620                flag_set(
621                    actions = all_link_actions,
622                    flag_groups = [flag_group(flags = ctx.attr.default_link_flags)],
623                ),
624            ],
625        )
626
627        static_link_msvcrt_feature = feature(
628            name = "static_link_msvcrt",
629            flag_sets = [
630                flag_set(
631                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
632                    flag_groups = [flag_group(flags = ["/MT"])],
633                    with_features = [with_feature_set(not_features = ["dbg"])],
634                ),
635                flag_set(
636                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
637                    flag_groups = [flag_group(flags = ["/MTd"])],
638                    with_features = [with_feature_set(features = ["dbg"])],
639                ),
640                flag_set(
641                    actions = all_link_actions,
642                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])],
643                    with_features = [with_feature_set(not_features = ["dbg"])],
644                ),
645                flag_set(
646                    actions = all_link_actions,
647                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])],
648                    with_features = [with_feature_set(features = ["dbg"])],
649                ),
650            ],
651        )
652
653        dynamic_link_msvcrt_feature = feature(
654            name = "dynamic_link_msvcrt",
655            enabled = True,
656            flag_sets = [
657                flag_set(
658                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
659                    flag_groups = [flag_group(flags = ["/MD"])],
660                    with_features = [with_feature_set(not_features = ["dbg", "static_link_msvcrt"])],
661                ),
662                flag_set(
663                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
664                    flag_groups = [flag_group(flags = ["/MDd"])],
665                    with_features = [with_feature_set(features = ["dbg"], not_features = ["static_link_msvcrt"])],
666                ),
667                flag_set(
668                    actions = all_link_actions,
669                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])],
670                    with_features = [with_feature_set(not_features = ["dbg", "static_link_msvcrt"])],
671                ),
672                flag_set(
673                    actions = all_link_actions,
674                    flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])],
675                    with_features = [with_feature_set(features = ["dbg"], not_features = ["static_link_msvcrt"])],
676                ),
677            ],
678        )
679
680        dbg_feature = feature(
681            name = "dbg",
682            flag_sets = [
683                flag_set(
684                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
685                    flag_groups = [flag_group(flags = ["/Od", "/Z7"])],
686                ),
687                flag_set(
688                    actions = all_link_actions,
689                    flag_groups = [
690                        flag_group(
691                            flags = [ctx.attr.dbg_mode_debug_flag, "/INCREMENTAL:NO"],
692                        ),
693                    ],
694                ),
695            ],
696            implies = ["generate_pdb_file"],
697        )
698
699        opt_feature = feature(
700            name = "opt",
701            flag_sets = [
702                flag_set(
703                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
704                    flag_groups = [flag_group(flags = ["/O2"])],
705                ),
706            ],
707            implies = ["frame_pointer"],
708        )
709
710        supports_interface_shared_libraries_feature = feature(
711            name = "supports_interface_shared_libraries",
712            enabled = True,
713        )
714
715        user_link_flags_feature = feature(
716            name = "user_link_flags",
717            flag_sets = [
718                flag_set(
719                    actions = all_link_actions,
720                    flag_groups = [
721                        flag_group(
722                            flags = ["%{user_link_flags}"],
723                            iterate_over = "user_link_flags",
724                            expand_if_available = "user_link_flags",
725                        ),
726                    ],
727                ),
728            ],
729        )
730
731        default_compile_flags_feature = feature(
732            name = "default_compile_flags",
733            enabled = True,
734            flag_sets = [
735                flag_set(
736                    actions = [
737                        ACTION_NAMES.assemble,
738                        ACTION_NAMES.preprocess_assemble,
739                        ACTION_NAMES.linkstamp_compile,
740                        ACTION_NAMES.c_compile,
741                        ACTION_NAMES.cpp_compile,
742                        ACTION_NAMES.cpp_header_parsing,
743                        ACTION_NAMES.cpp_module_compile,
744                        ACTION_NAMES.cpp_module_codegen,
745                        ACTION_NAMES.cpp_module_deps_scanning,
746                        ACTION_NAMES.cpp20_module_compile,
747                        ACTION_NAMES.cpp20_module_codegen,
748                        ACTION_NAMES.lto_backend,
749                        ACTION_NAMES.clif_match,
750                    ],
751                    flag_groups = [
752                        flag_group(
753                            flags = [
754                                "/DCOMPILER_MSVC",
755                                "/DNOMINMAX",
756                                "/D_WIN32_WINNT=0x0601",
757                                "/D_CRT_SECURE_NO_DEPRECATE",
758                                "/D_CRT_SECURE_NO_WARNINGS",
759                                "/bigobj",
760                                "/Zm500",
761                                "/EHsc",
762                                "/wd4351",
763                                "/wd4291",
764                                "/wd4250",
765                                "/wd4996",
766                            ],
767                        ),
768                    ],
769                ),
770            ],
771        )
772
773        msvc_compile_env_feature = feature(
774            name = "msvc_compile_env",
775            env_sets = [
776                env_set(
777                    actions = [
778                        ACTION_NAMES.c_compile,
779                        ACTION_NAMES.linkstamp_compile,
780                        ACTION_NAMES.cpp_compile,
781                        ACTION_NAMES.cpp_module_compile,
782                        ACTION_NAMES.cpp_module_codegen,
783                        ACTION_NAMES.cpp_header_parsing,
784                        ACTION_NAMES.cpp_module_deps_scanning,
785                        ACTION_NAMES.cpp20_module_compile,
786                        ACTION_NAMES.cpp20_module_codegen,
787                        ACTION_NAMES.assemble,
788                        ACTION_NAMES.preprocess_assemble,
789                    ],
790                    env_entries = [env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include)],
791                ),
792            ],
793        )
794
795        preprocessor_defines_feature = feature(
796            name = "preprocessor_defines",
797            enabled = True,
798            flag_sets = [
799                flag_set(
800                    actions = [
801                        ACTION_NAMES.assemble,
802                        ACTION_NAMES.preprocess_assemble,
803                        ACTION_NAMES.c_compile,
804                        ACTION_NAMES.linkstamp_compile,
805                        ACTION_NAMES.cpp_compile,
806                        ACTION_NAMES.cpp_header_parsing,
807                        ACTION_NAMES.cpp_module_compile,
808                        ACTION_NAMES.cpp_module_deps_scanning,
809                        ACTION_NAMES.cpp20_module_compile,
810                    ],
811                    flag_groups = [
812                        flag_group(
813                            flags = ["/D%{preprocessor_defines}"],
814                            iterate_over = "preprocessor_defines",
815                        ),
816                    ],
817                ),
818            ],
819        )
820
821        generate_pdb_file_feature = feature(
822            name = "generate_pdb_file",
823        )
824
825        generate_linkmap_feature = feature(
826            name = "generate_linkmap",
827            flag_sets = [
828                flag_set(
829                    actions = [
830                        ACTION_NAMES.cpp_link_executable,
831                    ],
832                    flag_groups = [
833                        flag_group(
834                            flags = [
835                                "/MAP:%{output_execpath}.map",
836                            ],
837                            expand_if_available = "output_execpath",
838                        ),
839                    ],
840                ),
841            ],
842        )
843
844        output_execpath_flags_feature = feature(
845            name = "output_execpath_flags",
846            flag_sets = [
847                flag_set(
848                    actions = all_link_actions,
849                    flag_groups = [
850                        flag_group(
851                            flags = ["/OUT:%{output_execpath}"],
852                            expand_if_available = "output_execpath",
853                        ),
854                    ],
855                ),
856            ],
857        )
858
859        disable_assertions_feature = feature(
860            name = "disable_assertions",
861            enabled = True,
862            flag_sets = [
863                flag_set(
864                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
865                    flag_groups = [flag_group(flags = ["/DNDEBUG"])],
866                    with_features = [with_feature_set(features = ["opt"])],
867                ),
868            ],
869        )
870
871        has_configured_linker_path_feature = feature(name = "has_configured_linker_path")
872
873        supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True)
874
875        no_stripping_feature = feature(name = "no_stripping")
876
877        linker_param_file_feature = feature(
878            name = "linker_param_file",
879            flag_sets = [
880                flag_set(
881                    actions = all_link_actions +
882                              [ACTION_NAMES.cpp_link_static_library],
883                    flag_groups = [
884                        flag_group(
885                            flags = ["@%{linker_param_file}"],
886                            expand_if_available = "linker_param_file",
887                        ),
888                    ],
889                ),
890            ],
891        )
892
893        ignore_noisy_warnings_feature = feature(
894            name = "ignore_noisy_warnings",
895            enabled = True,
896            flag_sets = [
897                flag_set(
898                    actions = [ACTION_NAMES.cpp_link_static_library],
899                    flag_groups = [flag_group(flags = ["/ignore:4221"])],
900                ),
901            ],
902        )
903
904        no_legacy_features_feature = feature(name = "no_legacy_features")
905
906        parse_showincludes_feature = feature(
907            name = "parse_showincludes",
908            enabled = ctx.attr.supports_parse_showincludes,
909            flag_sets = [
910                flag_set(
911                    actions = [
912                        ACTION_NAMES.preprocess_assemble,
913                        ACTION_NAMES.c_compile,
914                        ACTION_NAMES.linkstamp_compile,
915                        ACTION_NAMES.cpp_compile,
916                        ACTION_NAMES.cpp_module_compile,
917                        ACTION_NAMES.cpp_header_parsing,
918                        ACTION_NAMES.cpp_module_deps_scanning,
919                        ACTION_NAMES.cpp20_module_compile,
920                    ],
921                    flag_groups = [flag_group(flags = ["/showIncludes"])],
922                ),
923            ],
924            env_sets = [
925                env_set(
926                    actions = [
927                        ACTION_NAMES.preprocess_assemble,
928                        ACTION_NAMES.c_compile,
929                        ACTION_NAMES.linkstamp_compile,
930                        ACTION_NAMES.cpp_compile,
931                        ACTION_NAMES.cpp_module_compile,
932                        ACTION_NAMES.cpp_header_parsing,
933                    ],
934                    # Force English (and thus a consistent locale) output so that Bazel can parse
935                    # the /showIncludes output without having to guess the encoding.
936                    env_entries = [env_entry(key = "VSLANG", value = "1033")],
937                ),
938            ],
939        )
940
941        # MSVC does not emit .d files.
942        no_dotd_file_feature = feature(
943            name = "no_dotd_file",
944            enabled = True,
945        )
946
947        treat_warnings_as_errors_feature = feature(
948            name = "treat_warnings_as_errors",
949            flag_sets = [
950                flag_set(
951                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile] + all_link_actions,
952                    flag_groups = [flag_group(flags = ["/WX"])],
953                ),
954            ],
955        )
956
957        windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols")
958
959        no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols")
960
961        include_paths_feature = feature(
962            name = "include_paths",
963            enabled = True,
964            flag_sets = [
965                flag_set(
966                    actions = [
967                        ACTION_NAMES.assemble,
968                        ACTION_NAMES.preprocess_assemble,
969                        ACTION_NAMES.c_compile,
970                        ACTION_NAMES.linkstamp_compile,
971                        ACTION_NAMES.cpp_compile,
972                        ACTION_NAMES.cpp_header_parsing,
973                        ACTION_NAMES.cpp_module_compile,
974                    ],
975                    flag_groups = [
976                        flag_group(
977                            flags = ["/I%{quote_include_paths}"],
978                            iterate_over = "quote_include_paths",
979                        ),
980                        flag_group(
981                            flags = ["/I%{include_paths}"],
982                            iterate_over = "include_paths",
983                        ),
984                        flag_group(
985                            flags = ["/I%{system_include_paths}"],
986                            iterate_over = "system_include_paths",
987                        ),
988                    ],
989                ),
990            ],
991        )
992
993        external_include_paths_feature = feature(
994            name = "external_include_paths",
995            flag_sets = [
996                flag_set(
997                    actions = [
998                        ACTION_NAMES.preprocess_assemble,
999                        ACTION_NAMES.linkstamp_compile,
1000                        ACTION_NAMES.c_compile,
1001                        ACTION_NAMES.cpp_compile,
1002                        ACTION_NAMES.cpp_header_parsing,
1003                        ACTION_NAMES.cpp_module_compile,
1004                        ACTION_NAMES.cpp_module_deps_scanning,
1005                        ACTION_NAMES.cpp20_module_compile,
1006                        ACTION_NAMES.clif_match,
1007                        ACTION_NAMES.objc_compile,
1008                        ACTION_NAMES.objcpp_compile,
1009                    ],
1010                    flag_groups = [
1011                        flag_group(
1012                            flags = ["/external:I%{external_include_paths}"],
1013                            iterate_over = "external_include_paths",
1014                            expand_if_available = "external_include_paths",
1015                        ),
1016                    ],
1017                ),
1018            ],
1019        )
1020
1021        linkstamps_feature = feature(
1022            name = "linkstamps",
1023            flag_sets = [
1024                flag_set(
1025                    actions = all_link_actions,
1026                    flag_groups = [
1027                        flag_group(
1028                            flags = ["%{linkstamp_paths}"],
1029                            iterate_over = "linkstamp_paths",
1030                            expand_if_available = "linkstamp_paths",
1031                        ),
1032                    ],
1033                ),
1034            ],
1035        )
1036
1037        targets_windows_feature = feature(
1038            name = "targets_windows",
1039            enabled = True,
1040            implies = ["copy_dynamic_libraries_to_binary"],
1041        )
1042
1043        linker_subsystem_flag_feature = feature(
1044            name = "linker_subsystem_flag",
1045            flag_sets = [
1046                flag_set(
1047                    actions = all_link_actions,
1048                    flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])],
1049                ),
1050            ],
1051        )
1052
1053        frame_pointer_feature = feature(
1054            name = "frame_pointer",
1055            flag_sets = [
1056                flag_set(
1057                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1058                    flag_groups = [flag_group(flags = ["/Oy-"])],
1059                ),
1060            ],
1061        )
1062
1063        compiler_output_flags_feature = feature(
1064            name = "compiler_output_flags",
1065            flag_sets = [
1066                flag_set(
1067                    actions = [ACTION_NAMES.assemble],
1068                    flag_groups = [
1069                        flag_group(
1070                            flag_groups = [
1071                                flag_group(
1072                                    flags = ["/Fo%{output_file}", "/Zi"],
1073                                    expand_if_available = "output_file",
1074                                    expand_if_not_available = "output_assembly_file",
1075                                ),
1076                            ],
1077                            expand_if_not_available = "output_preprocess_file",
1078                        ),
1079                    ],
1080                ),
1081                flag_set(
1082                    actions = [
1083                        ACTION_NAMES.preprocess_assemble,
1084                        ACTION_NAMES.c_compile,
1085                        ACTION_NAMES.linkstamp_compile,
1086                        ACTION_NAMES.cpp_compile,
1087                        ACTION_NAMES.cpp_header_parsing,
1088                        ACTION_NAMES.cpp_module_compile,
1089                        ACTION_NAMES.cpp_module_codegen,
1090                        ACTION_NAMES.cpp_module_deps_scanning,
1091                        ACTION_NAMES.cpp20_module_compile,
1092                        ACTION_NAMES.cpp20_module_codegen,
1093                    ],
1094                    flag_groups = [
1095                        flag_group(
1096                            flag_groups = [
1097                                flag_group(
1098                                    flags = ["/Fo%{output_file}"],
1099                                    expand_if_not_available = "output_preprocess_file",
1100                                ),
1101                            ],
1102                            expand_if_available = "output_file",
1103                            expand_if_not_available = "output_assembly_file",
1104                        ),
1105                        flag_group(
1106                            flag_groups = [
1107                                flag_group(
1108                                    flags = ["/Fa%{output_file}"],
1109                                    expand_if_available = "output_assembly_file",
1110                                ),
1111                            ],
1112                            expand_if_available = "output_file",
1113                        ),
1114                        flag_group(
1115                            flag_groups = [
1116                                flag_group(
1117                                    flags = ["/P", "/Fi%{output_file}"],
1118                                    expand_if_available = "output_preprocess_file",
1119                                ),
1120                            ],
1121                            expand_if_available = "output_file",
1122                        ),
1123                    ],
1124                ),
1125            ],
1126        )
1127
1128        nologo_feature = feature(
1129            name = "nologo",
1130            flag_sets = [
1131                flag_set(
1132                    actions = [
1133                        ACTION_NAMES.c_compile,
1134                        ACTION_NAMES.linkstamp_compile,
1135                        ACTION_NAMES.cpp_compile,
1136                        ACTION_NAMES.cpp_module_compile,
1137                        ACTION_NAMES.cpp_module_codegen,
1138                        ACTION_NAMES.cpp_header_parsing,
1139                        ACTION_NAMES.cpp_module_deps_scanning,
1140                        ACTION_NAMES.cpp20_module_compile,
1141                        ACTION_NAMES.cpp20_module_codegen,
1142                        ACTION_NAMES.assemble,
1143                        ACTION_NAMES.preprocess_assemble,
1144                        ACTION_NAMES.cpp_link_executable,
1145                        ACTION_NAMES.cpp_link_dynamic_library,
1146                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1147                        ACTION_NAMES.cpp_link_static_library,
1148                    ],
1149                    flag_groups = [flag_group(flags = ["/nologo"])],
1150                ),
1151            ],
1152        )
1153
1154        smaller_binary_feature = feature(
1155            name = "smaller_binary",
1156            enabled = True,
1157            flag_sets = [
1158                flag_set(
1159                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1160                    flag_groups = [flag_group(flags = ["/Gy", "/Gw"])],
1161                    with_features = [with_feature_set(features = ["opt"])],
1162                ),
1163                flag_set(
1164                    actions = all_link_actions,
1165                    flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])],
1166                    with_features = [with_feature_set(features = ["opt"])],
1167                ),
1168            ],
1169        )
1170
1171        remove_unreferenced_code_feature = feature(
1172            name = "remove_unreferenced_code",
1173            enabled = True,
1174            flag_sets = [
1175                flag_set(
1176                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1177                    flag_groups = [flag_group(flags = ["/Zc:inline"])],
1178                ),
1179            ],
1180        )
1181
1182        compiler_input_flags_feature = feature(
1183            name = "compiler_input_flags",
1184            flag_sets = [
1185                flag_set(
1186                    actions = [
1187                        ACTION_NAMES.assemble,
1188                        ACTION_NAMES.preprocess_assemble,
1189                        ACTION_NAMES.c_compile,
1190                        ACTION_NAMES.linkstamp_compile,
1191                        ACTION_NAMES.cpp_compile,
1192                        ACTION_NAMES.cpp_header_parsing,
1193                        ACTION_NAMES.cpp_module_compile,
1194                        ACTION_NAMES.cpp_module_codegen,
1195                        ACTION_NAMES.cpp_module_deps_scanning,
1196                        ACTION_NAMES.cpp20_module_compile,
1197                        ACTION_NAMES.cpp20_module_codegen,
1198                    ],
1199                    flag_groups = [
1200                        flag_group(
1201                            flags = ["/c", "%{source_file}"],
1202                            expand_if_available = "source_file",
1203                        ),
1204                    ],
1205                ),
1206            ],
1207        )
1208
1209        def_file_feature = feature(
1210            name = "def_file",
1211            flag_sets = [
1212                flag_set(
1213                    actions = all_link_actions,
1214                    flag_groups = [
1215                        flag_group(
1216                            flags = ["/DEF:%{def_file_path}", "/ignore:4070"],
1217                            expand_if_available = "def_file_path",
1218                        ),
1219                    ],
1220                ),
1221            ],
1222        )
1223
1224        msvc_env_feature = feature(
1225            name = "msvc_env",
1226            env_sets = [
1227                env_set(
1228                    actions = [
1229                        ACTION_NAMES.c_compile,
1230                        ACTION_NAMES.linkstamp_compile,
1231                        ACTION_NAMES.cpp_compile,
1232                        ACTION_NAMES.cpp_module_compile,
1233                        ACTION_NAMES.cpp_module_codegen,
1234                        ACTION_NAMES.cpp_header_parsing,
1235                        ACTION_NAMES.cpp_module_deps_scanning,
1236                        ACTION_NAMES.cpp20_module_compile,
1237                        ACTION_NAMES.cpp20_module_codegen,
1238                        ACTION_NAMES.assemble,
1239                        ACTION_NAMES.preprocess_assemble,
1240                        ACTION_NAMES.cpp_link_executable,
1241                        ACTION_NAMES.cpp_link_dynamic_library,
1242                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1243                        ACTION_NAMES.cpp_link_static_library,
1244                    ],
1245                    env_entries = [
1246                        env_entry(key = "PATH", value = ctx.attr.msvc_env_path),
1247                        env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp),
1248                        env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp),
1249                    ],
1250                ),
1251            ],
1252            implies = ["msvc_compile_env", "msvc_link_env"],
1253        )
1254
1255        symbol_check_feature = feature(
1256            name = "symbol_check",
1257            flag_sets = [
1258                flag_set(
1259                    actions = [ACTION_NAMES.cpp_link_static_library],
1260                    flag_groups = [flag_group(flags = ["/WX:4006"])],
1261                ),
1262            ],
1263        )
1264
1265        features = [
1266            no_legacy_features_feature,
1267            nologo_feature,
1268            has_configured_linker_path_feature,
1269            no_stripping_feature,
1270            targets_windows_feature,
1271            copy_dynamic_libraries_to_binary_feature,
1272            default_compile_flags_feature,
1273            msvc_env_feature,
1274            msvc_compile_env_feature,
1275            msvc_link_env_feature,
1276            include_paths_feature,
1277            external_include_paths_feature,
1278            preprocessor_defines_feature,
1279            parse_showincludes_feature,
1280            no_dotd_file_feature,
1281            generate_pdb_file_feature,
1282            generate_linkmap_feature,
1283            shared_flag_feature,
1284            linkstamps_feature,
1285            output_execpath_flags_feature,
1286            archiver_flags_feature,
1287            input_param_flags_feature,
1288            linker_subsystem_flag_feature,
1289            user_link_flags_feature,
1290            default_link_flags_feature,
1291            linker_param_file_feature,
1292            static_link_msvcrt_feature,
1293            dynamic_link_msvcrt_feature,
1294            dbg_feature,
1295            fastbuild_feature,
1296            opt_feature,
1297            frame_pointer_feature,
1298            disable_assertions_feature,
1299            determinism_feature,
1300            treat_warnings_as_errors_feature,
1301            smaller_binary_feature,
1302            remove_unreferenced_code_feature,
1303            ignore_noisy_warnings_feature,
1304            user_compile_flags_feature,
1305            sysroot_feature,
1306            unfiltered_compile_flags_feature,
1307            archive_param_file_feature,
1308            compiler_param_file_feature,
1309            compiler_output_flags_feature,
1310            compiler_input_flags_feature,
1311            def_file_feature,
1312            windows_export_all_symbols_feature,
1313            no_windows_export_all_symbols_feature,
1314            supports_dynamic_linker_feature,
1315            supports_interface_shared_libraries_feature,
1316            symbol_check_feature,
1317        ]
1318    else:
1319        targets_windows_feature = feature(
1320            name = "targets_windows",
1321            implies = ["copy_dynamic_libraries_to_binary"],
1322            enabled = True,
1323        )
1324
1325        copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary")
1326
1327        gcc_env_feature = feature(
1328            name = "gcc_env",
1329            enabled = True,
1330            env_sets = [
1331                env_set(
1332                    actions = [
1333                        ACTION_NAMES.c_compile,
1334                        ACTION_NAMES.linkstamp_compile,
1335                        ACTION_NAMES.cpp_compile,
1336                        ACTION_NAMES.cpp_module_compile,
1337                        ACTION_NAMES.cpp_module_codegen,
1338                        ACTION_NAMES.cpp_header_parsing,
1339                        ACTION_NAMES.cpp_module_deps_scanning,
1340                        ACTION_NAMES.cpp20_module_compile,
1341                        ACTION_NAMES.cpp20_module_codegen,
1342                        ACTION_NAMES.assemble,
1343                        ACTION_NAMES.preprocess_assemble,
1344                        ACTION_NAMES.cpp_link_executable,
1345                        ACTION_NAMES.cpp_link_dynamic_library,
1346                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1347                        ACTION_NAMES.cpp_link_static_library,
1348                    ],
1349                    env_entries = [
1350                        env_entry(key = "PATH", value = ctx.attr.tool_bin_path),
1351                    ],
1352                ),
1353            ],
1354        )
1355
1356        default_compile_flags_feature = feature(
1357            name = "default_compile_flags",
1358            enabled = True,
1359            flag_sets = [
1360                flag_set(
1361                    actions = [
1362                        ACTION_NAMES.linkstamp_compile,
1363                        ACTION_NAMES.cpp_compile,
1364                        ACTION_NAMES.cpp_header_parsing,
1365                        ACTION_NAMES.cpp_module_compile,
1366                        ACTION_NAMES.cpp_module_codegen,
1367                        ACTION_NAMES.cpp_module_deps_scanning,
1368                        ACTION_NAMES.cpp20_module_compile,
1369                        ACTION_NAMES.cpp20_module_codegen,
1370                        ACTION_NAMES.lto_backend,
1371                        ACTION_NAMES.clif_match,
1372                    ],
1373                    flag_groups = [flag_group(flags = ["-std=gnu++14"] + ctx.attr.default_compile_flags)],
1374                ),
1375            ],
1376        )
1377
1378        default_link_flags_feature = feature(
1379            name = "default_link_flags",
1380            enabled = True,
1381            flag_sets = [
1382                flag_set(
1383                    actions = all_link_actions,
1384                    flag_groups = [flag_group(flags = ["-lstdc++"] + ctx.attr.default_link_flags)],
1385                ),
1386            ],
1387        )
1388
1389        supports_dynamic_linker_feature = feature(
1390            name = "supports_dynamic_linker",
1391            enabled = True,
1392        )
1393
1394        dbg_feature = feature(
1395            name = "dbg",
1396            flag_sets = [
1397                flag_set(
1398                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1399                    flag_groups = [flag_group(flags = ["-g", "-Og"])],
1400                ),
1401            ],
1402        )
1403
1404        opt_feature = feature(
1405            name = "opt",
1406            flag_sets = [
1407                flag_set(
1408                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1409                    flag_groups = [flag_group(flags = [
1410                        "-g0",
1411                        "-O3",
1412                        "-DNDEBUG",
1413                        "-ffunction-sections",
1414                        "-fdata-sections",
1415                    ])],
1416                ),
1417                flag_set(
1418                    actions = all_link_actions,
1419                    flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])],
1420                ),
1421            ],
1422        )
1423
1424        if ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc":
1425            archive_param_file_feature = feature(
1426                name = "archive_param_file",
1427                enabled = True,
1428            )
1429
1430            compiler_param_file_feature = feature(
1431                name = "compiler_param_file",
1432            )
1433
1434            features = [
1435                targets_windows_feature,
1436                copy_dynamic_libraries_to_binary_feature,
1437                gcc_env_feature,
1438                default_compile_flags_feature,
1439                archive_param_file_feature,
1440                compiler_param_file_feature,
1441                default_link_flags_feature,
1442                supports_dynamic_linker_feature,
1443                dbg_feature,
1444                opt_feature,
1445            ]
1446        else:
1447            supports_pic_feature = feature(
1448                name = "supports_pic",
1449                enabled = True,
1450            )
1451
1452            sysroot_feature = feature(
1453                name = "sysroot",
1454                enabled = True,
1455                flag_sets = [
1456                    flag_set(
1457                        actions = [
1458                            ACTION_NAMES.preprocess_assemble,
1459                            ACTION_NAMES.linkstamp_compile,
1460                            ACTION_NAMES.c_compile,
1461                            ACTION_NAMES.cpp_compile,
1462                            ACTION_NAMES.cpp_header_parsing,
1463                            ACTION_NAMES.cpp_module_compile,
1464                            ACTION_NAMES.cpp_module_codegen,
1465                            ACTION_NAMES.cpp_module_deps_scanning,
1466                            ACTION_NAMES.cpp20_module_compile,
1467                            ACTION_NAMES.cpp20_module_codegen,
1468                            ACTION_NAMES.lto_backend,
1469                            ACTION_NAMES.clif_match,
1470                            ACTION_NAMES.cpp_link_executable,
1471                            ACTION_NAMES.cpp_link_dynamic_library,
1472                            ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1473                        ],
1474                        flag_groups = [
1475                            flag_group(
1476                                flags = ["--sysroot=%{sysroot}"],
1477                                expand_if_available = "sysroot",
1478                            ),
1479                        ],
1480                    ),
1481                ],
1482            )
1483
1484            fdo_optimize_feature = feature(
1485                name = "fdo_optimize",
1486                flag_sets = [
1487                    flag_set(
1488                        actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1489                        flag_groups = [
1490                            flag_group(
1491                                flags = [
1492                                    "-fprofile-use=%{fdo_profile_path}",
1493                                    "-fprofile-correction",
1494                                ],
1495                                expand_if_available = "fdo_profile_path",
1496                            ),
1497                        ],
1498                    ),
1499                ],
1500                provides = ["profile"],
1501            )
1502
1503            treat_warnings_as_errors_feature = feature(
1504                name = "treat_warnings_as_errors",
1505                flag_sets = [
1506                    flag_set(
1507                        actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1508                        flag_groups = [flag_group(flags = ["-Werror"])],
1509                    ),
1510                    flag_set(
1511                        actions = all_link_actions,
1512                        flag_groups = [flag_group(flags = ["-Wl,-fatal-warnings"])],
1513                    ),
1514                ],
1515            )
1516
1517            user_compile_flags_feature = feature(
1518                name = "user_compile_flags",
1519                enabled = True,
1520                flag_sets = [
1521                    flag_set(
1522                        actions = [
1523                            ACTION_NAMES.assemble,
1524                            ACTION_NAMES.preprocess_assemble,
1525                            ACTION_NAMES.linkstamp_compile,
1526                            ACTION_NAMES.c_compile,
1527                            ACTION_NAMES.cpp_compile,
1528                            ACTION_NAMES.cpp_header_parsing,
1529                            ACTION_NAMES.cpp_module_compile,
1530                            ACTION_NAMES.cpp_module_codegen,
1531                            ACTION_NAMES.cpp_module_deps_scanning,
1532                            ACTION_NAMES.cpp20_module_compile,
1533                            ACTION_NAMES.cpp20_module_codegen,
1534                            ACTION_NAMES.lto_backend,
1535                            ACTION_NAMES.clif_match,
1536                        ],
1537                        flag_groups = [
1538                            flag_group(
1539                                flags = ["%{user_compile_flags}"],
1540                                iterate_over = "user_compile_flags",
1541                                expand_if_available = "user_compile_flags",
1542                            ),
1543                        ],
1544                    ),
1545                ],
1546            )
1547
1548            features = [
1549                targets_windows_feature,
1550                copy_dynamic_libraries_to_binary_feature,
1551                gcc_env_feature,
1552                supports_pic_feature,
1553                default_compile_flags_feature,
1554                default_link_flags_feature,
1555                fdo_optimize_feature,
1556                supports_dynamic_linker_feature,
1557                dbg_feature,
1558                opt_feature,
1559                user_compile_flags_feature,
1560                treat_warnings_as_errors_feature,
1561                sysroot_feature,
1562            ]
1563
1564    tool_paths = [
1565        tool_path(name = name, path = path)
1566        for name, path in ctx.attr.tool_paths.items()
1567    ]
1568
1569    make_variables = []
1570
1571    # dumpbin.exe is not available in MSYS toolchain
1572    if "dumpbin" in ctx.attr.tool_paths:
1573        make_variables.append(make_variable(name = "DUMPBIN", value = ctx.attr.tool_paths["dumpbin"]))
1574
1575    # Tell bazel we support C++ modules now
1576    cpp_modules_feature = feature(
1577        name = "cpp_modules",
1578        # set default value to False
1579        # to enable the feature
1580        # use --features=cpp_modules
1581        # or add cpp_modules to features attr
1582        enabled = False,
1583    )
1584
1585    cpp_module_modmap_file_feature = feature(
1586        name = "cpp_module_modmap_file",
1587        flag_sets = [
1588            flag_set(
1589                actions = [
1590                    ACTION_NAMES.cpp_compile,
1591                    ACTION_NAMES.cpp20_module_compile,
1592                    ACTION_NAMES.cpp20_module_codegen,
1593                ],
1594                flag_groups = [
1595                    flag_group(
1596                        flags = ["@%{cpp_module_modmap_file}"],
1597                        expand_if_available = "cpp_module_modmap_file",
1598                    ),
1599                ],
1600            ),
1601        ],
1602        enabled = True,
1603    )
1604    cpp20_module_compile_flags_feature = feature(
1605        name = "cpp20_module_compile_flags",
1606        flag_sets = [
1607            flag_set(
1608                actions = [
1609                    ACTION_NAMES.cpp20_module_compile,
1610                ],
1611                flag_groups = [
1612                    flag_group(
1613                        flags = ["/ifcOutput%{cpp_module_output_file}"],
1614                        expand_if_available = "cpp_module_output_file",
1615                    ),
1616                ],
1617            ),
1618        ],
1619        enabled = True,
1620    )
1621    return cc_common.create_cc_toolchain_config_info(
1622        ctx = ctx,
1623        features = features + [cpp_modules_feature, cpp_module_modmap_file_feature, cpp20_module_compile_flags_feature],
1624        action_configs = action_configs,
1625        artifact_name_patterns = artifact_name_patterns,
1626        cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories,
1627        toolchain_identifier = ctx.attr.toolchain_identifier,
1628        host_system_name = ctx.attr.host_system_name,
1629        target_system_name = ctx.attr.target_system_name,
1630        target_cpu = ctx.attr.cpu,
1631        target_libc = ctx.attr.target_libc,
1632        compiler = ctx.attr.compiler,
1633        abi_version = ctx.attr.abi_version,
1634        abi_libc_version = ctx.attr.abi_libc_version,
1635        tool_paths = tool_paths,
1636        make_variables = make_variables,
1637    )
1638
1639cc_toolchain_config = rule(
1640    implementation = _impl,
1641    attrs = {
1642        "abi_libc_version": attr.string(),
1643        "abi_version": attr.string(),
1644        "archiver_flags": attr.string_list(default = []),
1645        "compiler": attr.string(),
1646        "cpu": attr.string(mandatory = True),
1647        "cxx_builtin_include_directories": attr.string_list(),
1648        "dbg_mode_debug_flag": attr.string(default = ""),
1649        "default_compile_flags": attr.string_list(default = []),
1650        "default_link_flags": attr.string_list(default = []),
1651        "fastbuild_mode_debug_flag": attr.string(default = ""),
1652        "host_system_name": attr.string(),
1653        "msvc_cl_path": attr.string(default = "vc_installation_error.bat"),
1654        "msvc_env_include": attr.string(default = "msvc_not_found"),
1655        "msvc_env_lib": attr.string(default = "msvc_not_found"),
1656        "msvc_env_path": attr.string(default = "msvc_not_found"),
1657        "msvc_env_tmp": attr.string(default = "msvc_not_found"),
1658        "msvc_lib_path": attr.string(default = "vc_installation_error.bat"),
1659        "msvc_link_path": attr.string(default = "vc_installation_error.bat"),
1660        "msvc_ml_path": attr.string(default = "vc_installation_error.bat"),
1661        "supports_parse_showincludes": attr.bool(),
1662        "target_libc": attr.string(),
1663        "target_system_name": attr.string(),
1664        "tool_bin_path": attr.string(default = "not_found"),
1665        "tool_paths": attr.string_dict(),
1666        "toolchain_identifier": attr.string(),
1667    },
1668    provides = [CcToolchainConfigInfo],
1669)
1670