private void GenerateCompilerOptions()

in Sharpmake.Generators/VisualStudio/ProjectOptionsGenerator.cs [235:1209]


        private void GenerateCompilerOptions(IGenerationContext context, ProjectOptionsGenerationContext optionsContext)
        {
            var forcedIncludes = new Strings();

            bool useClang = context.Configuration.Platform.IsUsingClang();
            bool useClangCl = Options.GetObject<Options.Vc.General.PlatformToolset>(context.Configuration).IsLLVMToolchain() &&
                              Options.GetObject<Options.Vc.LLVM.UseClangCl>(context.Configuration) == Options.Vc.LLVM.UseClangCl.Enable;


            if (!context.Configuration.IsFastBuild)
            {
                // support of PCH requires them to be set as ForceIncludes with ClangCl
                if (useClangCl && !string.IsNullOrEmpty(context.Configuration.PrecompHeader))
                {
                    forcedIncludes.Add(context.Configuration.PrecompHeader);
                }
            }

            forcedIncludes.AddRange(context.Configuration.ForcedIncludes);

            if (forcedIncludes.Count > 0)
            {
                context.Options["ForcedIncludeFiles"] = forcedIncludes.JoinStrings(";");

                // save the vanilla value without the LLVM workaround for reuse later
                if (forcedIncludes.Count != context.Configuration.ForcedIncludes.Count)
                    context.Options["ForcedIncludeFilesVanilla"] = context.Configuration.ForcedIncludes.JoinStrings(";");

                StringBuilder result = new StringBuilder();
                var platformDescriptor = PlatformRegistry.Get<IPlatformDescriptor>(context.Configuration.Platform);
                string defaultCmdLineForceIncludePrefix = platformDescriptor.IsUsingClang ? @"-include""" : @"/FI""";
                foreach (var forcedInclude in forcedIncludes)
                    result.Append(defaultCmdLineForceIncludePrefix + forcedInclude + @""" ");
                result.Remove(result.Length - 1, 1);
                context.CommandLineOptions["ForcedIncludeFiles"] = result.ToString();
            }
            else
            {
                context.Options["ForcedIncludeFiles"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["ForcedIncludeFiles"] = FileGeneratorUtilities.RemoveLineTag;
            }

            if (optionsContext.PlatformDescriptor.IsUsingClang)
            {
                context.Options["CharacterSet"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["CharacterSet"] = FileGeneratorUtilities.RemoveLineTag;

                context.Options["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag;

                //https://clang.llvm.org/docs/CommandGuide/clang.html
                context.SelectOption
                (
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Default, () => { context.Options["ClangCppLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.Options["CppLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Cpp98, () => { context.Options["ClangCppLanguageStandard"] = "-std=c++98"; context.Options["CppLanguageStandard"] = "c++98"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Cpp11, () => { context.Options["ClangCppLanguageStandard"] = "-std=c++11"; context.Options["CppLanguageStandard"] = "c++11"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Cpp14, () => { context.Options["ClangCppLanguageStandard"] = "-std=c++14"; context.Options["CppLanguageStandard"] = "c++14"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Cpp17, () => { context.Options["ClangCppLanguageStandard"] = "-std=c++17"; context.Options["CppLanguageStandard"] = "c++17"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.Cpp2a, () => { context.Options["ClangCppLanguageStandard"] = "-std=c++2a"; context.Options["CppLanguageStandard"] = "c++2a"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.GnuCpp98, () => { context.Options["ClangCppLanguageStandard"] = "-std=gnu++98"; context.Options["CppLanguageStandard"] = "gnu++98"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.GnuCpp11, () => { context.Options["ClangCppLanguageStandard"] = "-std=gnu++11"; context.Options["CppLanguageStandard"] = "gnu++11"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.GnuCpp14, () => { context.Options["ClangCppLanguageStandard"] = "-std=gnu++14"; context.Options["CppLanguageStandard"] = "gnu++14"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.GnuCpp17, () => { context.Options["ClangCppLanguageStandard"] = "-std=gnu++17"; context.Options["CppLanguageStandard"] = "gnu++17"; }),
                Options.Option(Options.Clang.Compiler.CppLanguageStandard.GnuCpp2a, () => { context.Options["ClangCppLanguageStandard"] = "-std=gnu++2a"; context.Options["CppLanguageStandard"] = "gnu++2a"; })
                );

                context.SelectOption
                (
                Options.Option(Options.Clang.Compiler.CLanguageStandard.Default, () => { context.Options["ClangCLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.Options["CLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.C89, () => { context.Options["ClangCLanguageStandard"] = "-std=c89"; context.Options["CLanguageStandard"] = "c89"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.C90, () => { context.Options["ClangCLanguageStandard"] = "-std=c90"; context.Options["CLanguageStandard"] = "c90"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.C99, () => { context.Options["ClangCLanguageStandard"] = "-std=c99"; context.Options["CLanguageStandard"] = "c99"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.C11, () => { context.Options["ClangCLanguageStandard"] = "-std=c11"; context.Options["CLanguageStandard"] = "c11"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.C17, () => { context.Options["ClangCLanguageStandard"] = "-std=c17"; context.Options["CLanguageStandard"] = "c17"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.GnuC89, () => { context.Options["ClangCLanguageStandard"] = "-std=gnu89"; context.Options["CLanguageStandard"] = "gnu89"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.GnuC90, () => { context.Options["ClangCLanguageStandard"] = "-std=gnu90"; context.Options["CLanguageStandard"] = "gnu90"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.GnuC99, () => { context.Options["ClangCLanguageStandard"] = "-std=gnu99"; context.Options["CLanguageStandard"] = "gnu99"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.GnuC11, () => { context.Options["ClangCLanguageStandard"] = "-std=gnu11"; context.Options["CLanguageStandard"] = "gnu11"; }),
                Options.Option(Options.Clang.Compiler.CLanguageStandard.GnuC17, () => { context.Options["ClangCLanguageStandard"] = "-std=gnu17"; context.Options["CLanguageStandard"] = "gnu17"; })
                );

                context.CommandLineOptions["CppLanguageStd"] = context.Options["ClangCppLanguageStandard"];
                context.CommandLineOptions["CLanguageStd"] = context.Options["ClangCLanguageStandard"];
            }
            else
            {
                context.Options["ClangCppLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["ClangCppLanguageStandard"] = FileGeneratorUtilities.RemoveLineTag;

                //Options.Vc.General.CharacterSet.
                //    NotSet                                  CharacterSet="0"
                //    UseUnicodeCharaterSet                   Project.ProjectConfiguration.CharacterSet="1"                  /D "_UNICODE" /D "UNICODE"
                //    UseMultiByteCharaterSet                 Project.ProjectConfiguration.CharacterSet="2"                  /D "_MBCS"
                context.SelectOption
                (
                Options.Option(Options.Vc.General.CharacterSet.Default, () => { context.Options["CharacterSet"] = "NotSet"; context.CommandLineOptions["CharacterSet"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.General.CharacterSet.Unicode, () => { context.Options["CharacterSet"] = "Unicode"; context.CommandLineOptions["CharacterSet"] = @"/D""_UNICODE"" /D""UNICODE"""; }),
                Options.Option(Options.Vc.General.CharacterSet.MultiByte, () => { context.Options["CharacterSet"] = "MultiByte"; context.CommandLineOptions["CharacterSet"] = @"/D""_MBCS"""; })
                );

                //Options.Vc.Compiler.CppLanguageStandard.
                //    CPP98                                   LanguageStandard=""
                //    CPP11                                   LanguageStandard=""
                //    CPP14                                   LanguageStandard="stdcpp14"                                    /std:c++14
                //    CPP17                                   LanguageStandard="stdcpp17"                                    /std:c++17
                //    GNU98                                   LanguageStandard=""
                //    GNU11                                   LanguageStandard=""
                //    GNU14                                   LanguageStandard="stdcpp14"                                    /std:c++14
                //    GNU17                                   LanguageStandard="stdcpp17"                                    /std:c++17
                //    Latest                                  LanguageStandard="stdcpplatest"                                /std:c++latest
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.CPP98, () => { context.Options["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.CPP11, () => { context.Options["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.CPP14, () => { context.Options["LanguageStandard"] = "stdcpp14"; context.CommandLineOptions["LanguageStandard"] = "/std:c++14"; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.CPP17, () => { context.Options["LanguageStandard"] = "stdcpp17"; context.CommandLineOptions["LanguageStandard"] = "/std:c++17"; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.CPP20, () => { context.Options["LanguageStandard"] = "stdcpp20"; context.CommandLineOptions["LanguageStandard"] = "/std:c++20"; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.GNU98, () => { context.Options["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.GNU11, () => { context.Options["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LanguageStandard"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.GNU14, () => { context.Options["LanguageStandard"] = "stdcpp14"; context.CommandLineOptions["LanguageStandard"] = "/std:c++14"; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.GNU17, () => { context.Options["LanguageStandard"] = "stdcpp17"; context.CommandLineOptions["LanguageStandard"] = "/std:c++17"; }),
                Options.Option(Options.Vc.Compiler.CppLanguageStandard.Latest, () => { context.Options["LanguageStandard"] = "stdcpplatest"; context.CommandLineOptions["LanguageStandard"] = "/std:c++latest"; })
                );

                //Options.Vc.Compiler.CLanguageStandard.
                //    Legacy                                  LanguageStandard_C=""
                //    C11                                     LanguageStandard_C="stdc11"                                    /std:c11
                //    C17                                     LanguageStandard_C="stdc17"                                    /std:c17
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.CLanguageStandard.Legacy, () => { context.Options["LanguageStandard_C"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LanguageStandard_C"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CLanguageStandard.C11, () => { context.Options["LanguageStandard_C"] = "stdc11"; context.CommandLineOptions["LanguageStandard_C"] = "/std:c11"; }),
                Options.Option(Options.Vc.Compiler.CLanguageStandard.C17, () => { context.Options["LanguageStandard_C"] = "stdc17"; context.CommandLineOptions["LanguageStandard_C"] = "/std:c17"; })
                );
            }

            // Compiler section

            context.SelectOption
            (
            Options.Option(Options.Vc.General.TranslateIncludes.Enable, () => { context.Options["TranslateIncludes"] = "true"; context.CommandLineOptions["TranslateIncludes"] = "/translateInclude"; }),
            Options.Option(Options.Vc.General.TranslateIncludes.Disable, () => { context.Options["TranslateIncludes"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["TranslateIncludes"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            //Options.Vc.General.CommonLanguageRuntimeSupport.
            context.SelectOption
            (
            Options.Option(Options.Vc.General.CommonLanguageRuntimeSupport.NoClrSupport, () => { context.Options["CLRSupport"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["CLRSupport"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.CommonLanguageRuntimeSupport.ClrSupport, () => { context.Options["CLRSupport"] = "true"; context.CommandLineOptions["CLRSupport"] = "/clr"; }),
            Options.Option(Options.Vc.General.CommonLanguageRuntimeSupport.PureMsilClrSupport, () => { context.Options["CLRSupport"] = "Pure"; context.CommandLineOptions["CLRSupport"] = "/clr:pure"; }),
            Options.Option(Options.Vc.General.CommonLanguageRuntimeSupport.SafeMsilClrSupport, () => { context.Options["CLRSupport"] = "Safe"; context.CommandLineOptions["CLRSupport"] = "/clr:safe"; }),
            Options.Option(Options.Vc.General.CommonLanguageRuntimeSupport.ClrNetCoreSupport, () => { context.Options["CLRSupport"] = "NetCore"; context.CommandLineOptions["CLRSupport"] = "/clr:netcore"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.General.MfcSupport.UseMfcStdWin, () => { context.Options["UseOfMfc"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["UseOfMfc"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.MfcSupport.UseMfcStatic, () => { context.Options["UseOfMfc"] = "Static"; context.CommandLineOptions["UseOfMfc"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.MfcSupport.UseMfcDynamic, () => { context.Options["UseOfMfc"] = "Dynamic"; context.CommandLineOptions["UseOfMfc"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            //Options.Vc.General.WholeProgramOptimization.
            //    NoWholeProgramOptimization              WholeProgramOptimization="0"
            //    UseLinkTimeCodeGeneration               WholeProgramOptimization="1"                    /GL                                 /LTCG
            //    ProfileGuidedOptimizationInstrument     WholeProgramOptimization="2"                    /GL                                 /LTCG:PGINSTRUMENT
            //    ProfileGuidedOptimizationOptimize       WholeProgramOptimization="3"                    /GL                                 /LTCG:PGOPTIMIZE /PGD:"f:\coding\helloworld\helloworld\Debug\hellochange.pgd"
            //    ProfileGuidedOptimizationUpdate         WholeProgramOptimization="3"                    /GL                                 /LTCG:PGUPDATE /PGD:"f:\coding\helloworld\helloworld\Debug\hellochange.pgd"
            context.SelectOption
            (
            Options.Option(Options.Vc.General.WholeProgramOptimization.Disable, () => { context.Options["WholeProgramOptimization"] = "false"; context.Options["CompilerWholeProgramOptimization"] = "false"; context.CommandLineOptions["CompilerWholeProgramOptimization"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.WholeProgramOptimization.LinkTime, () => { context.Options["WholeProgramOptimization"] = "true"; context.Options["CompilerWholeProgramOptimization"] = "true"; context.CommandLineOptions["CompilerWholeProgramOptimization"] = "/GL"; }),
            Options.Option(Options.Vc.General.WholeProgramOptimization.Instrument, () => { context.Options["WholeProgramOptimization"] = "PGInstrument"; context.Options["CompilerWholeProgramOptimization"] = "true"; context.CommandLineOptions["CompilerWholeProgramOptimization"] = "/GL"; }),
            Options.Option(Options.Vc.General.WholeProgramOptimization.Optimize, () => { context.Options["WholeProgramOptimization"] = "PGOptimize"; context.Options["CompilerWholeProgramOptimization"] = "true"; context.CommandLineOptions["CompilerWholeProgramOptimization"] = "/GL"; }),
            Options.Option(Options.Vc.General.WholeProgramOptimization.Update, () => { context.Options["WholeProgramOptimization"] = "PGUpdate"; context.Options["CompilerWholeProgramOptimization"] = "true"; context.CommandLineOptions["CompilerWholeProgramOptimization"] = "/GL"; })
            );

            optionsContext.PlatformVcxproj.SelectApplicationFormatOptions(context);
            optionsContext.PlatformVcxproj.SelectBuildType(context);

            // Visual C++ Directories
            {
                // Path to use when searching for executable files while building a VC++ project.  Corresponds to environment variable PATH.
                context.Options["ExecutablePath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to use when searching for include files while building a VC++ project.  Corresponds to environment variable INCLUDE.
                context.Options["IncludePath"] = FileGeneratorUtilities.RemoveLineTag;

                // Vs2019+: Path to treat as external/system during compilation and skip in build up-to-date check.
                context.Options["ExternalIncludePath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to use when searching for metadata files while building a VC++ project. Corresponds to environment variable LIBPATH.
                context.Options["ReferencePath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to use when searching for library files while building a VC++ project.  Corresponds to environment variable LIB.
                context.Options["LibraryPath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to use when searching for winmd metadata files while building a VC++ project. Gets concatenated with 'Reference Directories' into LIBPATH.
                context.Options["LibraryWPath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to use when searching for source files to use for Intellisense.
                context.Options["SourcePath"] = FileGeneratorUtilities.RemoveLineTag;

                // Path to skip when searching for scan dependencies.
                context.Options["ExcludePath"] = FileGeneratorUtilities.RemoveLineTag;

                // One or more directories to automatically add to the include path in the referencing projects.
                context.Options["PublicIncludeDirectories"] = FileGeneratorUtilities.RemoveLineTag;

                // Specifies if directories or all project header files should be automatically added to the include path in the referencing projects.
                context.Options["AllProjectIncludesArePublic"] = FileGeneratorUtilities.RemoveLineTag;

                // One or more this project directories containing c++ module and/or header unit sources to make automatically available in the referencing projects.
                context.Options["PublicModuleDirectories"] = FileGeneratorUtilities.RemoveLineTag;

                // Specifies if all project modules and header units should be automatically available in the referencing projects.
                context.Options["AllProjectBMIsArePublic"] = FileGeneratorUtilities.RemoveLineTag;
            }

            context.Options["AdditionalUsingDirectories"] = FileGeneratorUtilities.RemoveLineTag;
            optionsContext.PlatformVcxproj.SetupSdkOptions(context);

            bool writeResourceCompileTag = optionsContext.PlatformVcxproj.GetResourceIncludePaths(context).Any();

            //Resource Compiler ShowProgress
            //    No                                      ShowProgress="false"
            //    Yes                                     ShowProgress="true"
            context.SelectOption
            (
            Options.Option(Options.Vc.ResourceCompiler.ShowProgress.No, () => { context.Options["ResourceCompilerShowProgress"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.ResourceCompiler.ShowProgress.Yes, () => { context.Options["ResourceCompilerShowProgress"] = "true"; writeResourceCompileTag = true; })
            );

            // Options.Vc.ResourceCompiler.PreprocessorDefinitions
            Strings resourcedefines = Options.GetStrings<Options.Vc.ResourceCompiler.PreprocessorDefinitions>(context.Configuration);
            if (resourcedefines.Any())
            {
                context.Options["ResourcePreprocessorDefinitions"] = resourcedefines.JoinStrings(";").Replace(@"""", GetPlatformStringResourceDefineQuote(context.Configuration.Platform));
                writeResourceCompileTag = true;
            }
            else
            {
                context.Options["ResourcePreprocessorDefinitions"] = FileGeneratorUtilities.RemoveLineTag;
            }

            context.Options["ResourceCompileTag"] = writeResourceCompileTag ? string.Empty : FileGeneratorUtilities.RemoveLineTag;

            //Options.Vc.General.DebugInformation.
            //    Disabled                                Project.ProjectConfiguration.Tool.DebugInformationFormat="0"
            //    C7Compatible                            Project.ProjectConfiguration.Tool.DebugInformationFormat="1"   /Z7
            //    ProgramDatabase                         Project.ProjectConfiguration.Tool.DebugInformationFormat="3"   /Zi
            //    ProgramDatabaseForEditAndContinue       Project.ProjectConfiguration.Tool.DebugInformationFormat="4"   /ZI

            SelectDebugInformationOption(context, optionsContext);

            context.SelectOption
            (
            Options.Option(Options.Vc.General.UseDebugLibraries.Disabled, () => { context.Options["UseDebugLibraries"] = "false"; }),
            Options.Option(Options.Vc.General.UseDebugLibraries.Enabled, () => { context.Options["UseDebugLibraries"] = "true"; })
            );

            //Options.Vc.General.WarningLevel.
            //    Level0                                  Project.ProjectConfiguration.Tool.WarningLevel="0"             /W0
            //    Level1                                  Project.ProjectConfiguration.Tool.WarningLevel="1"             /W1
            //    Level2                                  Project.ProjectConfiguration.Tool.WarningLevel="2"             /W2
            //    Level3                                  Project.ProjectConfiguration.Tool.WarningLevel="3"             /W3
            //    Level4                                  Project.ProjectConfiguration.Tool.WarningLevel="4"             /W4
            context.SelectOption
            (
            Options.Option(Options.Vc.General.WarningLevel.Level0, () => { context.Options["WarningLevel"] = "TurnOffAllWarnings"; context.CommandLineOptions["WarningLevel"] = "/W0"; }),
            Options.Option(Options.Vc.General.WarningLevel.Level1, () => { context.Options["WarningLevel"] = "Level1"; context.CommandLineOptions["WarningLevel"] = "/W1"; }),
            Options.Option(Options.Vc.General.WarningLevel.Level2, () => { context.Options["WarningLevel"] = "Level2"; context.CommandLineOptions["WarningLevel"] = "/W2"; }),
            Options.Option(Options.Vc.General.WarningLevel.Level3, () => { context.Options["WarningLevel"] = "Level3"; context.CommandLineOptions["WarningLevel"] = "/W3"; }),
            Options.Option(Options.Vc.General.WarningLevel.Level4, () => { context.Options["WarningLevel"] = "Level4"; context.CommandLineOptions["WarningLevel"] = "/W4"; }),
            Options.Option(Options.Vc.General.WarningLevel.EnableAllWarnings, () => { context.Options["WarningLevel"] = "EnableAllWarnings"; context.CommandLineOptions["WarningLevel"] = "/Wall"; })
            );

            //Options.Vc.General.TreatWarnigAsError.
            //    Disable                                 WarnAsError="false"
            //    Enable                                  WarnAsError="true"                              /WX
            context.SelectOption
            (
            Options.Option(Options.Vc.General.TreatWarningsAsErrors.Disable, () => { context.Options["TreatWarningAsError"] = "false"; context.CommandLineOptions["TreatWarningAsError"] = "/WX-"; }),
            Options.Option(Options.Vc.General.TreatWarningsAsErrors.Enable, () => { context.Options["TreatWarningAsError"] = "true"; context.CommandLineOptions["TreatWarningAsError"] = "/WX"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.General.DiagnosticsFormat.Classic, () => { context.Options["DiagnosticsFormat"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["DiagnosticsFormat"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.DiagnosticsFormat.Caret, () => { context.Options["DiagnosticsFormat"] = "Caret"; context.CommandLineOptions["DiagnosticsFormat"] = "/diagnostics:caret"; }),
            Options.Option(Options.Vc.General.DiagnosticsFormat.ColumnInfo, () => { context.Options["DiagnosticsFormat"] = "Column"; context.CommandLineOptions["DiagnosticsFormat"] = "/diagnostics:column"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.General.TreatAngleIncludeAsExternal.Enable, () => { context.Options["TreatAngleIncludeAsExternal"] = "true"; context.CommandLineOptions["TreatAngleIncludeAsExternal"] = "/external:anglebrackets"; }),
            Options.Option(Options.Vc.General.TreatAngleIncludeAsExternal.Disable, () => { context.Options["TreatAngleIncludeAsExternal"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["TreatAngleIncludeAsExternal"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.General.ExternalWarningLevel.Level0, () => { context.Options["ExternalWarningLevel"] = "TurnOffAllWarnings"; context.CommandLineOptions["ExternalWarningLevel"] = "/external:W0"; }),
            Options.Option(Options.Vc.General.ExternalWarningLevel.Level1, () => { context.Options["ExternalWarningLevel"] = "Level1"; context.CommandLineOptions["ExternalWarningLevel"] = "/external:W1"; }),
            Options.Option(Options.Vc.General.ExternalWarningLevel.Level2, () => { context.Options["ExternalWarningLevel"] = "Level2"; context.CommandLineOptions["ExternalWarningLevel"] = "/external:W2"; }),
            Options.Option(Options.Vc.General.ExternalWarningLevel.Level3, () => { context.Options["ExternalWarningLevel"] = "Level3"; context.CommandLineOptions["ExternalWarningLevel"] = "/external:W3"; }),
            Options.Option(Options.Vc.General.ExternalWarningLevel.Level4, () => { context.Options["ExternalWarningLevel"] = "Level4"; context.CommandLineOptions["ExternalWarningLevel"] = "/external:W4"; }),
            Options.Option(Options.Vc.General.ExternalWarningLevel.InheritWarningLevel, () => { context.Options["ExternalWarningLevel"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["ExternalWarningLevel"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.General.ExternalTemplatesDiagnostics.Enable, () => { context.Options["ExternalTemplatesDiagnostics"] = "true"; context.CommandLineOptions["ExternalTemplatesDiagnostics"] = "/external:templates-"; }),
            Options.Option(Options.Vc.General.ExternalTemplatesDiagnostics.Disable, () => { context.Options["ExternalTemplatesDiagnostics"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["ExternalTemplatesDiagnostics"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            context.Options["TrackFileAccess"] = FileGeneratorUtilities.RemoveLineTag;

            if (context.DevelopmentEnvironment.IsVisualStudio())
            {
                SelectPreferredToolArchitecture(context);
                SelectPlatformToolsetOption(context, optionsContext);
            }

            // Compiler.SuppressStartupBanner
            context.CommandLineOptions["SuppressStartupBanner"] = "/nologo";

            //Options.Vc.Compiler.MultiProcessorCompilation.
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.MultiProcessorCompilation.Enable, () => { context.Options["MultiProcessorCompilation"] = "true"; context.CommandLineOptions["MultiProcessorCompilation"] = "/MP"; }),
            Options.Option(Options.Vc.Compiler.MultiProcessorCompilation.Disable, () => { context.Options["MultiProcessorCompilation"] = "false"; context.CommandLineOptions["MultiProcessorCompilation"] = FileGeneratorUtilities.RemoveLineTag; })
            );


            //Options.Vc.Compiler.Optimization.
            //    Disable                                 Project.ProjectConfiguration.Tool.Optimization="0"             /Od
            //    MinimizeSize                            Project.ProjectConfiguration.Tool.Optimization="1"             /O1
            //    MaximizeSpeed                           Project.ProjectConfiguration.Tool.Optimization="2"             /O2
            //    FullOptimization                        Project.ProjectConfiguration.Tool.Optimization="3"             /Ox
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.Optimization.Disable, () => { context.Options["Optimization"] = "Disabled"; context.CommandLineOptions["Optimization"] = "/Od"; }),
            Options.Option(Options.Vc.Compiler.Optimization.MinimizeSize, () => { context.Options["Optimization"] = "MinSpace"; context.CommandLineOptions["Optimization"] = "/O1"; }),
            Options.Option(Options.Vc.Compiler.Optimization.MaximizeSpeed, () => { context.Options["Optimization"] = "MaxSpeed"; context.CommandLineOptions["Optimization"] = "/O2"; }),
            Options.Option(Options.Vc.Compiler.Optimization.FullOptimization, () => { context.Options["Optimization"] = "Full"; context.CommandLineOptions["Optimization"] = "/Ox"; })
            );

            //Options.Vc.Compiler.Inline.
            //    Default                                 InlineFunctionExpansion="0"
            //    OnlyInline                              InlineFunctionExpansion="1"                     /Ob1
            //    AnySuitable                             InlineFunctionExpansion="2"                     /Ob2
            //    Disable                                 InlineFunctionExpansion="3"                     /Ob0
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.Inline.Default, () => { context.Options["InlineFunctionExpansion"] = "Default"; context.CommandLineOptions["InlineFunctionExpansion"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.Inline.OnlyInline, () => { context.Options["InlineFunctionExpansion"] = "OnlyExplicitInline"; context.CommandLineOptions["InlineFunctionExpansion"] = "/Ob1"; }),
            Options.Option(Options.Vc.Compiler.Inline.AnySuitable, () => { context.Options["InlineFunctionExpansion"] = "AnySuitable"; context.CommandLineOptions["InlineFunctionExpansion"] = "/Ob2"; }),
            Options.Option(Options.Vc.Compiler.Inline.Disable, () => { context.Options["InlineFunctionExpansion"] = "Disabled"; context.CommandLineOptions["InlineFunctionExpansion"] = "/Ob0"; })
            );

            //Options.Vc.Compiler.Intrinsic.
            //    Disable                                 EnableIntrinsicFunctions="false"
            //    Enable                                  EnableIntrinsicFunctions="true"                 /Oi
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.Intrinsic.Disable, () => { context.Options["EnableIntrinsicFunctions"] = "false"; context.CommandLineOptions["EnableIntrinsicFunctions"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.Intrinsic.Enable, () => { context.Options["EnableIntrinsicFunctions"] = "true"; context.CommandLineOptions["EnableIntrinsicFunctions"] = "/Oi"; })
            );

            //Compiler.Optimization.FavorSizeOrSpeed
            //    Neither                                 FavorSizeOrSpeed="0"
            //    FavorFastCode                           FavorSizeOrSpeed="1"                            /Ot
            //    FavorSmallCode                          FavorSizeOrSpeed="2"                            /Os
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.FavorSizeOrSpeed.Neither, () => { context.Options["FavorSizeOrSpeed"] = "Neither"; context.CommandLineOptions["FavorSizeOrSpeed"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.FavorSizeOrSpeed.FastCode, () => { context.Options["FavorSizeOrSpeed"] = "Speed"; context.CommandLineOptions["FavorSizeOrSpeed"] = "/Ot"; }),
            Options.Option(Options.Vc.Compiler.FavorSizeOrSpeed.SmallCode, () => { context.Options["FavorSizeOrSpeed"] = "Size"; context.CommandLineOptions["FavorSizeOrSpeed"] = "/Os"; })
            );

            //Compiler.Optimization.OmitFramePointers
            //    Disable                                 OmitFramePointers="false"
            //    Enable                                  OmitFramePointers="true"                        /Oy
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.OmitFramePointers.Disable, () => { context.Options["OmitFramePointers"] = "false"; context.CommandLineOptions["OmitFramePointers"] = "/Oy-"; }),
            Options.Option(Options.Vc.Compiler.OmitFramePointers.Enable, () => { context.Options["OmitFramePointers"] = "true"; context.CommandLineOptions["OmitFramePointers"] = "/Oy"; })
            );

            //Compiler.Optimization.FiberSafe
            //    Disable                                 EnableFiberSafeOptimizations="false"
            //    Enable                                  EnableFiberSafeOptimizations="true"             /GT
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.FiberSafe.Disable, () => { context.Options["EnableFiberSafeOptimizations"] = "false"; context.CommandLineOptions["EnableFiberSafeOptimizations"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.FiberSafe.Enable, () => { context.Options["EnableFiberSafeOptimizations"] = "true"; context.CommandLineOptions["EnableFiberSafeOptimizations"] = "/GT"; })
            );

            //Compiler.IgnoreStandardIncludePath.
            //    Disable                                 IgnoreStandardIncludePath="false"
            //    Enable                                  IgnoreStandardIncludePath="true"                /X
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.IgnoreStandardIncludePath.Disable, () => { context.Options["IgnoreStandardIncludePath"] = "false"; context.CommandLineOptions["IgnoreStandardIncludePath"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.IgnoreStandardIncludePath.Enable, () => { context.Options["IgnoreStandardIncludePath"] = "true"; context.CommandLineOptions["IgnoreStandardIncludePath"] = "/X"; })
            );

            //Compiler.Proprocessor.GenerateProcessorFile
            //    Disable                                 GeneratePreprocessedFile="0"
            //    WithLineNumbers                         GeneratePreprocessedFile="1"                    /P
            //    WithoutLineNumbers                      GeneratePreprocessedFile="2"                    /EP /P
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.GenerateProcessorFile.Disable, () => { context.Options["GeneratePreprocessedFile"] = "false"; context.Options["PreprocessSuppressLineNumbers"] = "false"; context.CommandLineOptions["GeneratePreprocessedFile"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.GenerateProcessorFile.WithLineNumbers, () => { context.Options["GeneratePreprocessedFile"] = "true"; context.Options["PreprocessSuppressLineNumbers"] = "false"; context.CommandLineOptions["GeneratePreprocessedFile"] = "/P"; }),
            Options.Option(Options.Vc.Compiler.GenerateProcessorFile.WithoutLineNumbers, () => { context.Options["GeneratePreprocessedFile"] = "true"; context.Options["PreprocessSuppressLineNumbers"] = "true"; context.CommandLineOptions["GeneratePreprocessedFile"] = "/EP /P"; })
            );

            //Options.Vc.Compiler.KeepComment.
            //    Disable                                 KeepComments="false"
            //    Enable                                  KeepComments="true"                             /C
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.KeepComment.Disable, () => { context.Options["KeepComments"] = "false"; context.CommandLineOptions["KeepComments"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.KeepComment.Enable, () => { context.Options["KeepComments"] = "true"; context.CommandLineOptions["KeepComments"] = "/C"; })
            );

            //Options.Vc.Compiler.UseStandardConformingPreprocessor.    See: https://learn.microsoft.com/en-us/cpp/build/reference/zc-preprocessor?view=msvc-170
            //    Disable                                 /Zc:preprocessor-
            //    Enable                                  /Zc:preprocessor
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.UseStandardConformingPreprocessor.Default, () =>
            {
                context.Options["UseStandardConformingPreprocessor"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["UseStandardConformingPreprocessor"] = FileGeneratorUtilities.RemoveLineTag;
            }),
            Options.Option(Options.Vc.Compiler.UseStandardConformingPreprocessor.Disable, () =>
            {
                context.Options["UseStandardConformingPreprocessor"] = "false";
                context.CommandLineOptions["UseStandardConformingPreprocessor"] = "/Zc:preprocessor-";
            }),
            Options.Option(Options.Vc.Compiler.UseStandardConformingPreprocessor.Enable, () =>
            {
                context.Options["UseStandardConformingPreprocessor"] = "true";
                context.CommandLineOptions["UseStandardConformingPreprocessor"] = "/Zc:preprocessor";
            })
            );

            //Options.Vc.Compiler.StringPooling.
            //    Disable                                 StringPooling="false"
            //    Enable                                  StringPooling="true"                            /GF
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.StringPooling.Disable, () => { context.Options["StringPooling"] = "false"; context.CommandLineOptions["StringPooling"] = "/GF-"; }),
            Options.Option(Options.Vc.Compiler.StringPooling.Enable, () => { context.Options["StringPooling"] = "true"; context.CommandLineOptions["StringPooling"] = "/GF"; })
            );

            //Options.Vc.Compiler.Exceptions.
            //    Disable                                 ExceptionHandling="false"
            //    Enable                                  ExceptionHandling="Sync"                        /EHsc
            //    EnableWithExternC                       ExceptionHandling="SyncCThrow"                  /EHs
            //    EnableWithSEH                           ExceptionHandling="Async"                       /EHa
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.Exceptions.Disable, () => { context.Options["ExceptionHandling"] = "false"; context.CommandLineOptions["ExceptionHandling"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.Exceptions.Enable, () => { context.Options["ExceptionHandling"] = "Sync"; context.CommandLineOptions["ExceptionHandling"] = "/EHsc"; }),
            Options.Option(Options.Vc.Compiler.Exceptions.EnableWithExternC, () => { context.Options["ExceptionHandling"] = "SyncCThrow"; context.CommandLineOptions["ExceptionHandling"] = "/EHs"; }),
            Options.Option(Options.Vc.Compiler.Exceptions.EnableWithSEH, () => { context.Options["ExceptionHandling"] = "Async"; context.CommandLineOptions["ExceptionHandling"] = "/EHa"; })
            );

            context.Options["ForcedUsingFiles"] = FileGeneratorUtilities.RemoveLineTag;
            if (context.Configuration.ForceUsingFiles.Any() || context.Configuration.DependenciesForceUsingFiles.Any() || context.Configuration.ForceUsingDependencies.Any())
            {
                StringBuilder builder = new StringBuilder(context.Configuration.ForceUsingFiles.JoinStrings(";", true));
                if (context.Configuration.ForceUsingFiles.Any())
                    builder.Append(";");

                builder.Append(context.Configuration.DependenciesForceUsingFiles.JoinStrings(";"));
                if (context.Configuration.DependenciesForceUsingFiles.Any())
                    builder.Append(";");

                foreach (var dep in context.Configuration.ForceUsingDependencies)
                    builder.AppendFormat(@"{0}.dll;", dep.Project is CSharpProject ? dep.TargetFileName : dep.TargetFileFullName);
                string ForceUsingFiles = builder.ToString();
                context.Options["ForcedUsingFiles"] = ForceUsingFiles.Remove(ForceUsingFiles.Length - 1, 1);
            }

            //Options.Vc.Compiler.CompileAsWinRT.
            //    Disable                                 CompileAsWinRT="false"
            //    Enable                                  CompileAsWinRT="true"
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.CompileAsWinRT.Default, () => { context.Options["CompileAsWinRT"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.CompileAsWinRT.Disable, () => { context.Options["CompileAsWinRT"] = "false"; }),
            Options.Option(Options.Vc.Compiler.CompileAsWinRT.Enable, () => { context.Options["CompileAsWinRT"] = "true"; })
            );

            //Options.Vc.Compiler.TypeChecks.
            //    Disable                                 SmallerTypeCheck="true"                         /RTCc
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.TypeChecks.Disable, () => { context.Options["SmallerTypeCheck"] = "false"; context.CommandLineOptions["SmallerTypeCheck"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.TypeChecks.Enable, () => { context.Options["SmallerTypeCheck"] = "true"; context.CommandLineOptions["SmallerTypeCheck"] = "/RTCc"; })
            );

            //Options.Vc.Compiler.RuntimeChecks.
            //    Default                                 BasicRuntimeChecks="0"
            //    StackFrames                             BasicRuntimeChecks="1"                          /RTCs
            //    UninitializedVariables                  BasicRuntimeChecks="2"                          /RTCu
            //    Both                                    BasicRuntimeChecks="3"                          /RTC1
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.RuntimeChecks.Default, () => { context.Options["BasicRuntimeChecks"] = "Default"; context.CommandLineOptions["BasicRuntimeChecks"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.RuntimeChecks.StackFrames, () => { context.Options["BasicRuntimeChecks"] = "StackFrameRuntimeCheck"; context.CommandLineOptions["BasicRuntimeChecks"] = "/RTCs"; }),
            Options.Option(Options.Vc.Compiler.RuntimeChecks.UninitializedVariables, () => { context.Options["BasicRuntimeChecks"] = "UninitializedLocalUsageCheck"; context.CommandLineOptions["BasicRuntimeChecks"] = "/RTCu"; }),
            Options.Option(Options.Vc.Compiler.RuntimeChecks.Both, () => { context.Options["BasicRuntimeChecks"] = "EnableFastChecks"; context.CommandLineOptions["BasicRuntimeChecks"] = "/RTC1"; })
            );

            if (Util.IsCpp(context.Configuration))
            {
                //Options.Vc.Compiler.RuntimeLibrary.
                //    MultiThreaded                           RuntimeLibrary="0"                              /MT
                //    MultiThreadedDebug                      RuntimeLibrary="1"                              /MTd
                //    MultiThreadedDLL                        RuntimeLibrary="2"                              /MD
                //    MultiThreadedDebugDLL                   RuntimeLibrary="3"                              /MDd
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.RuntimeLibrary.MultiThreaded, () => { context.Options["RuntimeLibrary"] = "MultiThreaded"; context.CommandLineOptions["RuntimeLibrary"] = "/MT"; }),
                Options.Option(Options.Vc.Compiler.RuntimeLibrary.MultiThreadedDebug, () => { context.Options["RuntimeLibrary"] = "MultiThreadedDebug"; context.CommandLineOptions["RuntimeLibrary"] = "/MTd"; }),
                Options.Option(Options.Vc.Compiler.RuntimeLibrary.MultiThreadedDLL, () => { context.Options["RuntimeLibrary"] = "MultiThreadedDLL"; context.CommandLineOptions["RuntimeLibrary"] = "/MD"; }),
                Options.Option(Options.Vc.Compiler.RuntimeLibrary.MultiThreadedDebugDLL, () => { context.Options["RuntimeLibrary"] = "MultiThreadedDebugDLL"; context.CommandLineOptions["RuntimeLibrary"] = "/MDd"; })
                );
            }
            else
            {
                context.Options["RuntimeLibrary"] = FileGeneratorUtilities.RemoveLineTag;
            }

            bool clrSupport = Util.IsDotNet(context.Configuration);
            if (!clrSupport && context.DevelopmentEnvironment.IsVisualStudio() && context.DevelopmentEnvironment < DevEnv.vs2019) // Gm is deprecated starting with vs2019
            {
                //Options.Vc.Compiler.MinimalRebuild.
                //    Disable                                 MinimalRebuild="false"
                //    Enable                                  MinimalRebuild="true"                           /Gm
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.MinimalRebuild.Disable, () => { context.Options["MinimalRebuild"] = "false"; context.CommandLineOptions["MinimalRebuild"] = "/Gm-"; }),
                Options.Option(Options.Vc.Compiler.MinimalRebuild.Enable, () => { context.Options["MinimalRebuild"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["MinimalRebuild"] = "/Gm"; })
                );
            }
            else
            {
                context.Options["MinimalRebuild"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["MinimalRebuild"] = FileGeneratorUtilities.RemoveLineTag;
            }

            //Options.Vc.Compiler.RTTI.
            //    Disable                                 RuntimeTypeInfo="false"                         /GR-
            //    Enable                                  RuntimeTypeInfo="true"
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.RTTI.Disable, () => { context.Options["RuntimeTypeInfo"] = "false"; context.CommandLineOptions["RuntimeTypeInfo"] = "/GR-"; }),
            Options.Option(Options.Vc.Compiler.RTTI.Enable, () => { context.Options["RuntimeTypeInfo"] = "true"; context.CommandLineOptions["RuntimeTypeInfo"] = "/GR"; })
            );

            //Options.Vc.Compiler.StructAlignment.
            //    Default                                 StructMemberAlignment="0"
            //    Alignment1                              StructMemberAlignment="1"                       /Zp1
            //    Alignment2                              StructMemberAlignment="2"                       /Zp2
            //    Alignment4                              StructMemberAlignment="3"                       /Zp4
            //    Alignment8                              StructMemberAlignment="4"                       /Zp8
            //    Alignment16                             StructMemberAlignment="5"                       /Zp16
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.StructAlignment.Default, () => { context.Options["StructMemberAlignment"] = "Default"; context.CommandLineOptions["StructMemberAlignment"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.StructAlignment.Alignment1, () => { context.Options["StructMemberAlignment"] = "1Byte"; context.CommandLineOptions["StructMemberAlignment"] = "/Zp1"; }),
            Options.Option(Options.Vc.Compiler.StructAlignment.Alignment2, () => { context.Options["StructMemberAlignment"] = "2Bytes"; context.CommandLineOptions["StructMemberAlignment"] = "/Zp2"; }),
            Options.Option(Options.Vc.Compiler.StructAlignment.Alignment4, () => { context.Options["StructMemberAlignment"] = "4Bytes"; context.CommandLineOptions["StructMemberAlignment"] = "/Zp4"; }),
            Options.Option(Options.Vc.Compiler.StructAlignment.Alignment8, () => { context.Options["StructMemberAlignment"] = "8Bytes"; context.CommandLineOptions["StructMemberAlignment"] = "/Zp8"; }),
            Options.Option(Options.Vc.Compiler.StructAlignment.Alignment16, () => { context.Options["StructMemberAlignment"] = "16Bytes"; context.CommandLineOptions["StructMemberAlignment"] = "/Zp16"; })
            );

            //Options.Vc.Compiler.BufferSecurityCheck.
            //    Enable                                  BufferSecurityCheck="true"
            //    Disable                                 BufferSecurityCheck="false"                     /GS-
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.BufferSecurityCheck.Enable, () => { context.Options["BufferSecurityCheck"] = "true"; context.CommandLineOptions["BufferSecurityCheck"] = "/GS"; }),
            Options.Option(Options.Vc.Compiler.BufferSecurityCheck.Disable, () => { context.Options["BufferSecurityCheck"] = "false"; context.CommandLineOptions["BufferSecurityCheck"] = "/GS-"; })
            );

            //Options.Vc.Compiler.OptimizeGlobalData.
            //    Disable                                 /Gw- in AdditionalOptions
            //    Enable                                  /Gw in AdditionalOptions
            if (context.Configuration.Platform.IsMicrosoft())
            {
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.OptimizeGlobalData.Disable, () =>
                { /* do nothing */
                }),
                Options.Option(Options.Vc.Compiler.OptimizeGlobalData.Enable, () => { context.Configuration.AdditionalCompilerOptions.Add("/Gw"); })
                );
            }

            //Options.Vc.Compiler.FunctionLevelLinking.
            //    Disable                                 EnableFunctionLevelLinking="false"
            //    Enable                                  EnableFunctionLevelLinking="true"               /Gy
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.FunctionLevelLinking.Disable, () => { context.Options["EnableFunctionLevelLinking"] = "false"; context.CommandLineOptions["EnableFunctionLevelLinking"] = "/Gy-"; }),
            Options.Option(Options.Vc.Compiler.FunctionLevelLinking.Enable, () => { context.Options["EnableFunctionLevelLinking"] = "true"; context.CommandLineOptions["EnableFunctionLevelLinking"] = "/Gy"; })
            );

            //Options.Vc.Compiler.EnhancedInstructionSet.
            //    Disable                                 EnableEnhancedInstructionSet
            //    SIMD                                    EnableEnhancedInstructionSet                /arch:SSE
            //    SIMD2                                   EnableEnhancedInstructionSet                /arch:SSE2
            //    AdvancedVectorExtensions                EnableEnhancedInstructionSet                /arch:AVX
            //    NoEnhancedInstructions                  EnableEnhancedInstructionSet                /arch:IA32
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.Disable, () => { context.Options["EnableEnhancedInstructionSet"] = "NotSet"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.SIMD, () => { context.Options["EnableEnhancedInstructionSet"] = "StreamingSIMDExtensions"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:SSE"; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.SIMD2, () => { context.Options["EnableEnhancedInstructionSet"] = "StreamingSIMDExtensions2"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:SSE2"; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.AdvancedVectorExtensions, () => { context.Options["EnableEnhancedInstructionSet"] = "AdvancedVectorExtensions"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:AVX"; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.AdvancedVectorExtensions2, () => { context.Options["EnableEnhancedInstructionSet"] = "AdvancedVectorExtensions2"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:AVX2"; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.AdvancedVectorExtensions512, () => { context.Options["EnableEnhancedInstructionSet"] = "AdvancedVectorExtensions512"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:AVX512"; }),
            Options.Option(Options.Vc.Compiler.EnhancedInstructionSet.NoEnhancedInstructions, () => { context.Options["EnableEnhancedInstructionSet"] = "NoExtensions"; context.CommandLineOptions["EnableEnhancedInstructionSet"] = "/arch:IA32"; })
            );

            //Options.Vc.Compiler.FloatingPointModel.
            //    Precise                                 FloatingPointModel="0"                          /fp:precise
            //    Strict                                  FloatingPointModel="1"                          /fp:strict
            //    Fast                                    FloatingPointModel="2"                          /fp:fast
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.FloatingPointModel.Precise, () => { context.Options["FloatingPointModel"] = "Precise"; context.CommandLineOptions["FloatingPointModel"] = "/fp:precise"; }),
            Options.Option(Options.Vc.Compiler.FloatingPointModel.Strict, () => { context.Options["FloatingPointModel"] = "Strict"; context.CommandLineOptions["FloatingPointModel"] = "/fp:strict"; }),
            Options.Option(Options.Vc.Compiler.FloatingPointModel.Fast, () => { context.Options["FloatingPointModel"] = "Fast"; context.CommandLineOptions["FloatingPointModel"] = "/fp:fast"; })
            );

            //Options.Vc.Compiler.FloatingPointExceptions.
            //    Disable                                 FloatingPointExceptions="false"
            //    Enable                                  FloatingPointExceptions="true"                  /fp:except
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.FloatingPointExceptions.Disable, () => { context.Options["FloatingPointExceptions"] = "false"; context.CommandLineOptions["FloatingPointExceptions"] = "/fp:except-"; }),
            Options.Option(Options.Vc.Compiler.FloatingPointExceptions.Enable, () => { context.Options["FloatingPointExceptions"] = "true"; context.CommandLineOptions["FloatingPointExceptions"] = "/fp:except"; })
            );

            //Options.Vc.Compiler.CreateHotPatchableCode.
            //    Disable                                 CreateHotPatchableCode="false"
            //    Enable                                  CreateHotPatchableCode="true"                  /hotpatch
            context.SelectOption
            (
                Options.Option(Options.Vc.Compiler.CreateHotPatchableCode.Default, () => { context.Options["CompilerCreateHotpatchableImage"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["CompilerCreateHotpatchableImage"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CreateHotPatchableCode.Disable, () => { context.Options["CompilerCreateHotpatchableImage"] = "false"; context.CommandLineOptions["CompilerCreateHotpatchableImage"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.CreateHotPatchableCode.Enable, () => { context.Options["CompilerCreateHotpatchableImage"] = "true"; context.CommandLineOptions["CompilerCreateHotpatchableImage"] = "/hotpatch"; })
            );

            //Options.Vc.Compiler.ConformanceMode.
            //    Disable                                 ConformanceMode="false"
            //    Enable                                  ConformanceMode="true"                          /permissive-
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.ConformanceMode.Disable, () => { context.Options["ConformanceMode"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["ConformanceMode"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.ConformanceMode.Enable, () => { context.Options["ConformanceMode"] = "true"; context.CommandLineOptions["ConformanceMode"] = "/permissive-"; })
            );

            //Options.Vc.Compiler.DisableLanguageExtensions.
            //    Disable                                 DisableLanguageExtensions="false"
            //    Enable                                  DisableLanguageExtensions="true"                /Za
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.DisableLanguageExtensions.Disable, () => { context.Options["DisableLanguageExtensions"] = "false"; context.CommandLineOptions["DisableLanguageExtensions"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.DisableLanguageExtensions.Enable, () => { context.Options["DisableLanguageExtensions"] = "true"; context.CommandLineOptions["DisableLanguageExtensions"] = "/Za"; })
            );

            //Options.Vc.Compiler.BuiltInWChartType.
            //    Disable                                 TreatWChar_tAsBuiltInType="false"               /Zc:wchar_t-
            //    Enable                                  TreatWChar_tAsBuiltInType="true"                /Zc:wchar_t
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.BuiltInWChartType.Disable, () => { context.Options["TreatWChar_tAsBuiltInType"] = "false"; context.CommandLineOptions["TreatWChar_tAsBuiltInType"] = "/Zc:wchar_t-"; }),
            Options.Option(Options.Vc.Compiler.BuiltInWChartType.Enable, () => { context.Options["TreatWChar_tAsBuiltInType"] = "true"; context.CommandLineOptions["TreatWChar_tAsBuiltInType"] = "/Zc:wchar_t"; })
            );

            //    Disable                                 RemoveUnreferencedCodeData="false"
            //    Enable                                  RemoveUnreferencedCodeData="true"                /Zc:inline
            if (!context.DevelopmentEnvironment.IsVisualStudio())
            {
                context.Options["RemoveUnreferencedCodeData"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["RemoveUnreferencedCodeData"] = FileGeneratorUtilities.RemoveLineTag;
            }
            else
            {
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.RemoveUnreferencedCodeData.Disable, () =>
                {
                    context.Options["RemoveUnreferencedCodeData"] = "false";
                    context.CommandLineOptions["RemoveUnreferencedCodeData"] = FileGeneratorUtilities.RemoveLineTag;
                }),
                Options.Option(Options.Vc.Compiler.RemoveUnreferencedCodeData.Enable, () =>
                {
                    context.Options["RemoveUnreferencedCodeData"] = FileGeneratorUtilities.RemoveLineTag;
                    context.CommandLineOptions["RemoveUnreferencedCodeData"] = "/Zc:inline";
                })
                );
            }

            //Options.Vc.Compiler.ForceLoopScope.
            //    Disable                                 ForceConformanceInForLoopScope="false"          /Zc:forScope-
            //    Enable                                  ForceConformanceInForLoopScope="true"           /Zc:forScope
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.ForceLoopScope.Disable, () => { context.Options["ForceConformanceInForLoopScope"] = "false"; context.CommandLineOptions["ForceConformanceInForLoopScope"] = "/Zc:forScope-"; }),
            Options.Option(Options.Vc.Compiler.ForceLoopScope.Enable, () => { context.Options["ForceConformanceInForLoopScope"] = "true"; context.CommandLineOptions["ForceConformanceInForLoopScope"] = "/Zc:forScope"; })
            );

            //Options.Vc.Compiler.OpenMP.
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.OpenMP.Default, () => { context.Options["OpenMP"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["OpenMP"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.OpenMP.Disable, () => { context.Options["OpenMP"] = "false"; context.CommandLineOptions["OpenMP"] = "/openmp-"; }),
            Options.Option(Options.Vc.Compiler.OpenMP.Enable, () => { context.Options["OpenMP"] = "true"; context.CommandLineOptions["OpenMP"] = "/openmp"; })
            );

            //Options.Vc.Compiler.GenerateXMLDocumentation.
            //    Disable                                 GenerateXMLDocumentation="false"
            //    Enable                                  GenerateXMLDocumentation="true"                                   /openmp
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.GenerateXMLDocumentation.Disable, () => { context.Options["GenerateXMLDocumentation"] = "false"; context.CommandLineOptions["GenerateXMLDocumentation"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.GenerateXMLDocumentation.Enable, () => { context.Options["GenerateXMLDocumentation"] = "true"; context.CommandLineOptions["GenerateXMLDocumentation"] = @"/doc""[project.RootPath]"""; })
            );

            //Options.Vc.Compiler.PrecompiledHeader
            //      NotUsingPrecompiledHeaders          UsePrecompiledHeader="0"
            //      CreatePrecompiledHeader             UsePrecompiledHeader="1"                            /Yc
            //      UsePrecompiledHeader                UsePrecompiledHeader="2"                            /Yu
            SelectPrecompiledHeaderOption(context, optionsContext);

            //Options.Vc.Compiler.CallingConvention.
            //    cdecl                                   CallingConvention="0"                           /Gd
            //    fastcall                                CallingConvention="1"                           /Gr
            //    stdcall                                 CallingConvention="2"                           /Gz
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.CallingConvention.cdecl, () => { context.Options["CallingConvention"] = "Cdecl"; context.CommandLineOptions["CallingConvention"] = "/Gd"; }),
            Options.Option(Options.Vc.Compiler.CallingConvention.fastcall, () => { context.Options["CallingConvention"] = "FastCall"; context.CommandLineOptions["CallingConvention"] = "/Gr"; }),
            Options.Option(Options.Vc.Compiler.CallingConvention.stdcall, () => { context.Options["CallingConvention"] = "StdCall"; context.CommandLineOptions["CallingConvention"] = "/Gz"; }),
            Options.Option(Options.Vc.Compiler.CallingConvention.vectorcall, () => { context.Options["CallingConvention"] = "VectorCall"; context.CommandLineOptions["CallingConvention"] = "/Gv"; })
            );

            //Options.Vc.Compiler.ShowIncludes.
            //    Disable                               ShowIncludes="false"
            //    Enable                                ShowIncludes="true"                           /showIncludes
            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.ShowIncludes.Disable, () => { context.Options["ShowIncludes"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.ShowIncludes.Enable, () => { context.Options["ShowIncludes"] = "true"; })
            );

            // '/JMC' and '/clr' command-line options are incompatible
            if (!clrSupport)
            {
                //Options.Vc.Compiler.SupportJustMyCode.
                //    Yes                                   SupportJustMyCode="true"                          /JMC
                //    No
                context.SelectOption
                (
                Options.Option(Options.Vc.Compiler.SupportJustMyCode.Default, () => { context.Options["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Compiler.SupportJustMyCode.No, () =>
                {
                    if (context.DevelopmentEnvironment >= DevEnv.vs2017)
                    {
                        context.Options["SupportJustMyCode"] = "false";
                        context.CommandLineOptions["SupportJustMyCode"] = "/JMC-";
                    }
                    else
                    {
                        context.Options["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag;
                        context.CommandLineOptions["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag;
                    }
                }),
                Options.Option(Options.Vc.Compiler.SupportJustMyCode.Yes, () => { context.Options["SupportJustMyCode"] = "true"; context.CommandLineOptions["SupportJustMyCode"] = "/JMC"; })
                );
            }
            else
            {
                context.Options["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["SupportJustMyCode"] = FileGeneratorUtilities.RemoveLineTag;
            }

            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.SpectreMitigation.Default, () => { context.Options["SpectreMitigation"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["SpectreMitigation"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.SpectreMitigation.Spectre, () => { context.Options["SpectreMitigation"] = "Spectre"; context.CommandLineOptions["SpectreMitigation"] = "/Qspectre"; }),
            Options.Option(Options.Vc.Compiler.SpectreMitigation.SpectreLoad, () => { context.Options["SpectreMitigation"] = "SpectreLoad"; context.CommandLineOptions["SpectreMitigation"] = "/Qspectre-load"; }),
            Options.Option(Options.Vc.Compiler.SpectreMitigation.SpectreLoadCF, () => { context.Options["SpectreMitigation"] = "SpectreLoadCF"; context.CommandLineOptions["SpectreMitigation"] = "/Qspectre-load-cf"; }),
            Options.Option(Options.Vc.Compiler.SpectreMitigation.Disabled, () => { context.Options["SpectreMitigation"] = "false"; context.CommandLineOptions["SpectreMitigation"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.EnableAsan.Disable, () => { context.Options["EnableASAN"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["EnableASAN"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Compiler.EnableAsan.Enable, () => { context.Options["EnableASAN"] = "true"; context.CommandLineOptions["EnableASAN"] = "/fsanitize=address"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.Compiler.JumboBuild.Disable, () => 
            {
                context.Options["JumboBuild"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["MaxFilesPerJumboFile"] = FileGeneratorUtilities.RemoveLineTag; 
                context.Options["MinFilesPerJumboFile"] = FileGeneratorUtilities.RemoveLineTag; 
                context.Options["MinJumboFiles"] = FileGeneratorUtilities.RemoveLineTag; 
            }),
            Options.Option(Options.Vc.Compiler.JumboBuild.Enable, () =>
            {
                context.Options["JumboBuild"] = "true";
                context.Options["MaxFilesPerJumboFile"] = context.Configuration.MaxFilesPerJumboFile.ToString();
                context.Options["MinFilesPerJumboFile"] = context.Configuration.MinFilesPerJumboFile.ToString();
                context.Options["MinJumboFiles"] = context.Configuration.MinJumboFiles.ToString();
            })
            );

            if (context.DevelopmentEnvironment.IsVisualStudio() && context.DevelopmentEnvironment >= DevEnv.vs2017)
            {
                //Options.Vc.Compiler.DefineCPlusPlus. See: https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
                //    Disable                                 /Zc:__cplusplus-
                //    Enable                                  /Zc:__cplusplus
                if (!useClangCl)
                {
                    if (!context.Configuration.Platform.IsUsingClang())
                    {
                        context.SelectOption
                        (
                        Options.Option(Options.Vc.Compiler.DefineCPlusPlus.Default, () => { }),
                        Options.Option(Options.Vc.Compiler.DefineCPlusPlus.Disable, () => { context.Configuration.AdditionalCompilerOptions.Add("/Zc:__cplusplus-"); }),
                        Options.Option(Options.Vc.Compiler.DefineCPlusPlus.Enable, () => { context.Configuration.AdditionalCompilerOptions.Add("/Zc:__cplusplus"); })
                        );
                    }
                }
            }

            // Options.Vc.Compiler.DisableSpecificWarnings
            Strings disableWarnings = Options.GetStrings<Options.Vc.Compiler.DisableSpecificWarnings>(context.Configuration);
            if (disableWarnings.Count > 0)
            {
                StringBuilder result = new StringBuilder();
                foreach (string disableWarning in disableWarnings.SortedValues)
                    result.Append(@"/wd""" + disableWarning + @""" ");
                result.Remove(result.Length - 1, 1);
                context.Options["DisableSpecificWarnings"] = disableWarnings.JoinStrings(";");
                context.CommandLineOptions["DisableSpecificWarnings"] = result.ToString();
            }
            else
            {
                context.Options["DisableSpecificWarnings"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["DisableSpecificWarnings"] = FileGeneratorUtilities.RemoveLineTag;
            }

            // Options.Vc.Compiler.UndefinePreprocessorDefinitions
            Strings undefinePreprocessors = Options.GetStrings<Options.Vc.Compiler.UndefinePreprocessorDefinitions>(context.Configuration);
            if (undefinePreprocessors.Count > 0)
            {
                context.Options["UndefinePreprocessorDefinitions"] = undefinePreprocessors.JoinStrings(";");

                StringBuilder result = new StringBuilder();
                foreach (string undefine in undefinePreprocessors)
                    result.Append(@"/U""" + undefine + @""" ");
                result.Remove(result.Length - 1, 1);
                context.CommandLineOptions["UndefinePreprocessorDefinitions"] = result.ToString();
            }
            else
            {
                context.Options["UndefinePreprocessorDefinitions"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["UndefinePreprocessorDefinitions"] = FileGeneratorUtilities.RemoveLineTag;
            }

            // UndefineAllPreprocessorDefinitions
            context.CommandLineOptions["UndefineAllPreprocessorDefinitions"] = FileGeneratorUtilities.RemoveLineTag;

            optionsContext.PlatformVcxproj.SelectPrecompiledHeaderOptions(context);

            // Default defines...
            optionsContext.PlatformVcxproj.SelectCompilerOptions(context);

            if (useClangCl && context.Configuration.IsFastBuild)
            {
                // This prevents clang-cl from auto-detecting the locally installed MSVC toolchain. Only paths on the command line will be considered.
                // It doesn't apply on MSVC build, where the toolchain is provided through environment variables.
                context.Configuration.AdditionalCompilerOptions.Add("-nostdinc");
            }

            List<string> optionResults = new List<string>();
            // Options.Vc.Compiler.AdditionalOptions
            foreach (Tuple<OrderableStrings, string> optionsTuple in new[]
                    {
                        Tuple.Create(context.Configuration.AdditionalCompilerOptions, "AdditionalCompilerOptions"),
                        Tuple.Create(context.Configuration.AdditionalCompilerOptimizeOptions, "AdditionalCompilerOptimizeOptions"),
                        Tuple.Create(context.Configuration.AdditionalCompilerOptionsOnPCHCreate, "AdditionalCompilerOptionsOnPCHCreate"),
                        Tuple.Create(context.Configuration.AdditionalCompilerOptionsOnPCHUse, "AdditionalCompilerOptionsOnPCHUse")
                    })
            {
                OrderableStrings optionsStrings = optionsTuple.Item1;
                string optionsKey = optionsTuple.Item2;
                if (optionsStrings.Any())
                {
                    optionsStrings.Sort();
                    string additionalCompilerOptions = optionsStrings.JoinStrings(" ");
                    optionResults.Add(additionalCompilerOptions);
                    context.Options[optionsKey] = additionalCompilerOptions;
                }
                else
                {
                    optionResults.Add(FileGeneratorUtilities.RemoveLineTag);
                    context.Options[optionsKey] = FileGeneratorUtilities.RemoveLineTag;
                }
            }

            // We need to merge together AdditionalCompilerOptions and AdditionalCompilerOptimizeOptions for writing them on a single line in vcxproj files.
            string[] allAdditionalOptions = new string[] { optionResults[0], optionResults[1] };
            var nonEmptyOptions = allAdditionalOptions.Where(a => a != FileGeneratorUtilities.RemoveLineTag);
            if (nonEmptyOptions.Any())
            {
                context.Options["AllAdditionalCompilerOptions"] = string.Join(" ", nonEmptyOptions);
            }
            else
            {
                context.Options["AllAdditionalCompilerOptions"] = FileGeneratorUtilities.RemoveLineTag;
            }

            optionsContext.HasClrSupport = clrSupport;

            //--------------------------------
            // MSVC NMake IntelliSence options
            //--------------------------------

            // Handle C++ language version option
            string intellisenseCppLanguageStandard;
            if (!context.CommandLineOptions.TryGetValue("LanguageStandard", out intellisenseCppLanguageStandard) || intellisenseCppLanguageStandard == FileGeneratorUtilities.RemoveLineTag)
            {
                if (!context.CommandLineOptions.TryGetValue("CppLanguageStd", out intellisenseCppLanguageStandard))
                    intellisenseCppLanguageStandard = FileGeneratorUtilities.RemoveLineTag;
            }

            if (intellisenseCppLanguageStandard != FileGeneratorUtilities.RemoveLineTag)
            {
                if (useClangCl || useClang)
                {
                    // need to use a special syntax when compiler is clang/clangcl or Visual Studio will generate intellisense errors
                    intellisenseCppLanguageStandard = intellisenseCppLanguageStandard.Replace("/std:c++", "/Clangstdc++");
                    intellisenseCppLanguageStandard = intellisenseCppLanguageStandard.Replace("-std=c++", "/Clangstdc++");
                }
            }

            // Merge the intellisense language option with additional intellisense command line options
            string intellisenseCommandLineOptions = intellisenseCppLanguageStandard;
            Strings intellisenseAdditionalCommandlineOptions = context.Configuration.IntellisenseAdditionalCommandLineOptions;
            if (intellisenseAdditionalCommandlineOptions != null)
            {
                if (intellisenseCommandLineOptions != FileGeneratorUtilities.RemoveLineTag)
                    intellisenseCommandLineOptions += " ";
                intellisenseCommandLineOptions += string.Join(' ', intellisenseAdditionalCommandlineOptions);
            }
            context.Options["IntellisenseCommandLineOptions"] = intellisenseCommandLineOptions;

            // Add additional defines for intellisense to the default ones set for that target.
            Strings intellisenseDefines = context.Configuration.IntellisenseAdditionalDefines;
            context.Options["IntellisenseAdditionalDefines"] = intellisenseDefines != null ? ";" + String.Join(';', intellisenseDefines) : "";
        }