private void GenerateLinkerOptions()

in Sharpmake.Generators/VisualStudio/ProjectOptionsGenerator.cs [1339:1878]


        private void GenerateLinkerOptions(IGenerationContext context, ProjectOptionsGenerationContext optionsContext)
        {
            var configurationTasks = PlatformRegistry.Get<Project.Configuration.IConfigurationTasks>(context.Configuration.Platform);

            context.Options["ImportLibrary"] = FileGeneratorUtilities.RemoveLineTag;
            context.CommandLineOptions["ImportLibrary"] = FileGeneratorUtilities.RemoveLineTag;
            context.Options["OutputFileName"] = context.Configuration.TargetFileFullName;
            context.Options["OutputFileExtension"] = context.Configuration.TargetFileFullExtension;

            context.Options["AdditionalDeploymentFolders"] = "";

            switch (context.Configuration.Output)
            {
                case Project.Configuration.OutputType.AppleApp:
                    var conf = context.Configuration;
                    context.Options["OutputFile"] = Path.Combine(optionsContext.OutputDirectoryRelative, conf.TargetFileFullNameWithExtension, AppleAppBinaryRootFolder(conf.Platform), conf.TargetFileName);
                    break;
                case Project.Configuration.OutputType.Dll:
                case Project.Configuration.OutputType.DotNetClassLibrary:
                case Project.Configuration.OutputType.Exe:
                case Project.Configuration.OutputType.DotNetConsoleApp:
                case Project.Configuration.OutputType.DotNetWindowsApp:
                case Project.Configuration.OutputType.AppleFramework:
                case Project.Configuration.OutputType.AppleBundle:
                case Project.Configuration.OutputType.IosTestBundle:
                    context.Options["OutputFile"] = optionsContext.OutputDirectoryRelative + Util.WindowsSeparator + context.Configuration.TargetFileFullNameWithExtension;
                    if (context.Configuration.Output == Project.Configuration.OutputType.Dll)
                    {
                        string importLibRelative = optionsContext.OutputLibraryDirectoryRelative + Util.WindowsSeparator + context.Configuration.TargetFileFullName + ".lib";
                        context.Options["ImportLibrary"] = importLibRelative;
                        context.CommandLineOptions["ImportLibrary"] = "/IMPLIB:" + FormatCommandLineOptionPath(context, importLibRelative);
                    }
                    break;
                case Project.Configuration.OutputType.Lib:
                    context.Options["OutputFile"] = optionsContext.OutputLibraryDirectoryRelative + Util.WindowsSeparator + context.Configuration.TargetFileFullNameWithExtension;
                    break;
                case Project.Configuration.OutputType.Utility:
                case Project.Configuration.OutputType.None:
                    context.Options["OutputFile"] = FileGeneratorUtilities.RemoveLineTag;
                    context.Options["OutputFileExtension"] = FileGeneratorUtilities.RemoveLineTag;
                    context.Options["OutputFileName"] = FileGeneratorUtilities.RemoveLineTag;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.ShowProgress.NotSet, () => { context.Options["ShowProgress"] = "NotSet"; context.CommandLineOptions["ShowProgress"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerbose, () => { context.Options["ShowProgress"] = "LinkVerbose"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE"; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerboseLib, () => { context.Options["ShowProgress"] = "LinkVerboseLib"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE:Lib"; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerboseICF, () => { context.Options["ShowProgress"] = "LinkVerboseICF"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE:ICF"; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerboseREF, () => { context.Options["ShowProgress"] = "LinkVerboseREF"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE:REF"; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerboseSAFESEH, () => { context.Options["ShowProgress"] = "LinkVerboseSAFESEH"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE:SAFESEH"; }),
            Options.Option(Options.Vc.Linker.ShowProgress.LinkVerboseCLR, () => { context.Options["ShowProgress"] = "LinkVerboseCLR"; context.CommandLineOptions["ShowProgress"] = "/VERBOSE:CLR"; })
            );

            //Incremental
            //    Default                                 LinkIncremental="0"
            //    Disable                                 LinkIncremental="1"                         /INCREMENTAL:NO
            //    Enable                                  LinkIncremental="2"                         /INCREMENTAL
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.Incremental.Default, () => { context.Options["LinkIncremental"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LinkIncremental"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.Incremental.Disable, () => { context.Options["LinkIncremental"] = "false"; context.CommandLineOptions["LinkIncremental"] = "/INCREMENTAL:NO"; }),
            Options.Option(Options.Vc.Linker.Incremental.Enable, () => { context.Options["LinkIncremental"] = "true"; context.CommandLineOptions["LinkIncremental"] = "/INCREMENTAL"; })
            );

            //EmbedManifest
            //    Yes                                 EmbedManifest="true"
            //    No                                  EmbedManifest="false"
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.EmbedManifest.Default, () => { context.Options["EmbedManifest"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.EmbedManifest.Yes, () => { context.Options["EmbedManifest"] = "true"; }),
            Options.Option(Options.Vc.Linker.EmbedManifest.No, () => { context.Options["EmbedManifest"] = "false"; })
            );

            //SuppressStartupBanner
            //    Disable                                 SuppressStartupBanner="false"
            //    Enable                                  SuppressStartupBanner="true"                /NOLOGO
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.SuppressStartupBanner.Disable, () => { context.Options["SuppressStartupBanner"] = "false"; context.CommandLineOptions["LinkerSuppressStartupBanner"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.SuppressStartupBanner.Enable, () => { context.Options["SuppressStartupBanner"] = "true"; context.CommandLineOptions["LinkerSuppressStartupBanner"] = "/NOLOGO"; })
            );

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

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

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

            //IgnoreImportLibrary
            //    Enable                                  IgnoreImportLibrary="true"
            //    Disable                                 IgnoreImportLibrary="false"
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.IgnoreImportLibrary.Enable, () => { context.Options["IgnoreImportLibrary"] = "true"; }),
            Options.Option(Options.Vc.Linker.IgnoreImportLibrary.Disable, () => { context.Options["IgnoreImportLibrary"] = "false"; })
            );

            if (Options.GetObject<Options.Vc.CodeAnalysis.RunCodeAnalysis>(context.Configuration) == Options.Vc.CodeAnalysis.RunCodeAnalysis.Enable)
            {
                if (context.Configuration.IsFastBuild)
                    throw new NotImplementedException("Sharpmake does not support code analysis in fastbuild targets yet!");

                //RunCodeAnalysis
                //    Enable                                  RunCodeAnalysis="true"
                context.Options["RunCodeAnalysis"] = "true";

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

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

                //Code analysis excludes paths
                context.Options["CAexcludePaths"] = string.Join(";", Options.GetObjects<Options.Vc.CodeAnalysis.CodeAnalysisExcludePaths>(context.Configuration).Select(optionPath => optionPath.Path));
            }
            else
            {
                //RunCodeAnalysis
                //    Disable                                  nothing
                context.Options["RunCodeAnalysis"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["MicrosoftCodeAnalysis"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["ClangTidyCodeAnalysis"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["CAexcludePaths"] = FileGeneratorUtilities.RemoveLineTag;
            }


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

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

            //EnableManagedIncrementalBuild
            context.SelectOption
            (
            Options.Option(Options.Vc.General.EnableManagedIncrementalBuild.Enable, () => { context.Options["EnableManagedIncrementalBuild"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.General.EnableManagedIncrementalBuild.Disable, () => { context.Options["EnableManagedIncrementalBuild"] = "false"; })
            );

            //RandomizedBaseAddress
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.RandomizedBaseAddress.Default, () => { context.Options["RandomizedBaseAddress"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["RandomizedBaseAddress"] = "/DYNAMICBASE"; }),
            Options.Option(Options.Vc.Linker.RandomizedBaseAddress.Enable, () => { context.Options["RandomizedBaseAddress"] = "true"; context.CommandLineOptions["RandomizedBaseAddress"] = "/DYNAMICBASE"; }),
            Options.Option(Options.Vc.Linker.RandomizedBaseAddress.Disable, () => { context.Options["RandomizedBaseAddress"] = "false"; context.CommandLineOptions["RandomizedBaseAddress"] = "/DYNAMICBASE:NO"; })
            );

            // Delay Loaded DLLs
            Strings delayedDLLs = Options.GetStrings<Options.Vc.Linker.DelayLoadDLLs>(context.Configuration);
            if (delayedDLLs.Any())
            {
                context.Options["DelayLoadedDLLs"] = delayedDLLs.JoinStrings(";");

                StringBuilder result = new StringBuilder();
                foreach (string delayedDLL in delayedDLLs)
                    result.Append(@"/DELAYLOAD:""" + delayedDLL + @""" ");
                result.Remove(result.Length - 1, 1);
                context.CommandLineOptions["DelayLoadedDLLs"] = result.ToString();
            }
            else
            {
                context.Options["DelayLoadedDLLs"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["DelayLoadedDLLs"] = FileGeneratorUtilities.RemoveLineTag;
            }

            // Set module definition
            if (!string.IsNullOrEmpty(context.Configuration.ModuleDefinitionFile))
            {
                var filePath = Util.PathGetRelative(context.ProjectDirectory, context.Configuration.ModuleDefinitionFile);
                context.Options["ModuleDefinitionFile"] = filePath;
                context.CommandLineOptions["ModuleDefinitionFile"] = "/DEF:" + FormatCommandLineOptionPath(context, filePath);
            }
            else
            {
                context.Options["ModuleDefinitionFile"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["ModuleDefinitionFile"] = FileGeneratorUtilities.RemoveLineTag;
            }

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

            //GenerateManifest
            //    Enable                                  GenerateManifest="true"                 /MANIFEST
            //    Disable                                 GenerateManifest="false"
            SelectGenerateManifestOption(context, optionsContext);

            SelectGenerateDebugInformationOption(context, optionsContext);

            // GenerateMapFile
            SelectGenerateMapFileOption(context, optionsContext);

            //MapExports
            //    Enable                                  MapExports="true"                       /MAPINFO:EXPORTS
            //    Disable                                 MapExports="false"
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.MapExports.Enable, () => { context.Options["MapExports"] = "true"; context.CommandLineOptions["MapExports"] = "/MAPINFO:EXPORTS"; }),
            Options.Option(Options.Vc.Linker.MapExports.Disable, () => { context.Options["MapExports"] = "false"; context.CommandLineOptions["MapExports"] = FileGeneratorUtilities.RemoveLineTag; })
            );

            //AssemblyDebug
            //    NoDebuggableAttributeEmitted            AssemblyDebug="0"
            //    RuntimeTrackingAndDisableOptimizations  AssemblyDebug="1"                       /ASSEMBLYDEBUG
            //    NoRuntimeTrackingAndEnableOptimizations  AssemblyDebug="2"                       /ASSEMBLYDEBUG:DISABLE
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.AssemblyDebug.NoDebuggableAttributeEmitted, () => { context.Options["AssemblyDebug"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["AssemblyDebug"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.AssemblyDebug.RuntimeTrackingAndDisableOptimizations, () => { context.Options["AssemblyDebug"] = "true"; context.CommandLineOptions["AssemblyDebug"] = "/ASSEMBLYDEBUG"; }),
            Options.Option(Options.Vc.Linker.AssemblyDebug.NoRuntimeTrackingAndEnableOptimizations, () => { context.Options["AssemblyDebug"] = "false"; context.CommandLineOptions["AssemblyDebug"] = "/ASSEMBLYDEBUG:DISABLE"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.SubSystem.NotSet, () => { context.Options["SubSystem"] = "NotSet"; context.CommandLineOptions["SubSystem"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.SubSystem.Console, () => { context.Options["SubSystem"] = "Console"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:CONSOLE"; }),
            Options.Option(Options.Vc.Linker.SubSystem.Windows, () => { context.Options["SubSystem"] = "Windows"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:WINDOWS"; }),
            Options.Option(Options.Vc.Linker.SubSystem.Native, () => { context.Options["SubSystem"] = "Native"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:NATIVE"; }),
            Options.Option(Options.Vc.Linker.SubSystem.EFI_Application, () => { context.Options["SubSystem"] = "EFI Application"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:EFI_APPLICATION"; }),
            Options.Option(Options.Vc.Linker.SubSystem.EFI_Boot_Service_Driver, () => { context.Options["SubSystem"] = "EFI Boot Service Driver"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER"; }),
            Options.Option(Options.Vc.Linker.SubSystem.EFI_ROM, () => { context.Options["SubSystem"] = "EFI ROM"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:EFI_ROM"; }),
            Options.Option(Options.Vc.Linker.SubSystem.EFI_Runtime, () => { context.Options["SubSystem"] = "EFI Runtime"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:EFI_RUNTIME_DRIVER"; }),
            Options.Option(Options.Vc.Linker.SubSystem.POSIX, () => { context.Options["SubSystem"] = "POSIX"; context.CommandLineOptions["SubSystem"] = "/SUBSYSTEM:POSIX"; })
            );


            //HeapSize
            //HeapReserveSize
            //                                            HeapReserveSize="0"                     /HEAP:reserve
            //HeapCommitSize
            //                                            HeapCommitSize="0"                      /HEAP:reserve,commit
            Options.Vc.Linker.HeapSize heap = Options.GetObject<Options.Vc.Linker.HeapSize>(context.Configuration);
            if (heap == null)
            {
                context.Options["HeapReserveSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["HeapCommitSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["HeapReserveSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["HeapCommitSize"] = FileGeneratorUtilities.RemoveLineTag;
            }
            else
            {
                context.Options["HeapReserveSize"] = heap.ReserveSize.ToString();
                context.Options["HeapCommitSize"] = heap.CommintSize.ToString();
                context.CommandLineOptions["HeapReserveSize"] = "/HEAP:reserve";
                context.CommandLineOptions["HeapCommitSize"] = "/HEAP:reserve,commit";
            }

            //StackSize
            //StackReserveSize
            //                                            StackReserveSize="0"                    /STACK:reserve
            //StackCommitSize
            //                                            StackCommitSize="0"                     /STACK:reserve,commit
            Options.Vc.Linker.StackSize stack = Options.GetObject<Options.Vc.Linker.StackSize>(context.Configuration);
            if (stack == null)
            {
                context.Options["StackReserveSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["StackCommitSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["StackReserveSize"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["StackCommitSize"] = FileGeneratorUtilities.RemoveLineTag;
            }
            else
            {
                context.Options["StackReserveSize"] = stack.ReserveSize.ToString();
                context.Options["StackCommitSize"] = stack.CommintSize.ToString();
                if (stack.CommintSize > 0)
                {
                    context.CommandLineOptions["StackReserveSize"] = FileGeneratorUtilities.RemoveLineTag;
                    context.CommandLineOptions["StackCommitSize"] = "/STACK:" + stack.ReserveSize + "," + stack.CommintSize;
                }
                else
                {
                    context.CommandLineOptions["StackReserveSize"] = "/STACK:" + stack.ReserveSize;
                    context.CommandLineOptions["StackCommitSize"] = FileGeneratorUtilities.RemoveLineTag;
                }
            }

            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.AllowIsolation.Enabled, () => { context.Options["AllowIsolation"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["AllowIsolation"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.AllowIsolation.Disabled, () => { context.Options["AllowIsolation"] = "false"; context.CommandLineOptions["AllowIsolation"] = "/ALLOWISOLATION:NO"; })
            );

            //LargeAddress
            //    Default                                 LargeAddressAware="0"
            //    NotSupportLargerThan2Gb                 LargeAddressAware="1"                   /LARGEADDRESSAWARE:NO
            //    SupportLargerThan2Gb                    LargeAddressAware="2"                   /LARGEADDRESSAWARE
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.LargeAddress.Default, () => { context.Options["LargeAddressAware"] = "true"; context.CommandLineOptions["LargeAddressAware"] = "/LARGEADDRESSAWARE"; }),
            Options.Option(Options.Vc.Linker.LargeAddress.NotSupportLargerThan2Gb, () => { context.Options["LargeAddressAware"] = "false"; context.CommandLineOptions["LargeAddressAware"] = "/LARGEADDRESSAWARE:NO"; }),
            Options.Option(Options.Vc.Linker.LargeAddress.SupportLargerThan2Gb, () => { context.Options["LargeAddressAware"] = "true"; context.CommandLineOptions["LargeAddressAware"] = "/LARGEADDRESSAWARE"; })
            );

            Options.Vc.Linker.BaseAddress baseAddress = Options.GetObject<Options.Vc.Linker.BaseAddress>(context.Configuration);
            if (baseAddress != null && baseAddress.Value.Length > 0)
            {
                context.Options["BaseAddress"] = baseAddress.Value;
                context.CommandLineOptions["BaseAddress"] = @"/BASE:""" + (baseAddress.Value) + @"""";
            }
            else
            {
                context.Options["BaseAddress"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["BaseAddress"] = FileGeneratorUtilities.RemoveLineTag;
            }

            //Reference
            //    Default                                 OptimizeReferences="0"
            //    KeepUnreferencedData                    OptimizeReferences="1"                  /OPT:NOREF
            //    EliminateUnreferencedData               OptimizeReferences="2"                  /OPT:REF
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.Reference.KeepUnreferencedData, () => { context.Options["OptimizeReferences"] = "false"; context.CommandLineOptions["OptimizeReference"] = "/OPT:NOREF"; }),
            Options.Option(Options.Vc.Linker.Reference.EliminateUnreferencedData, () => { context.Options["OptimizeReferences"] = "true"; context.CommandLineOptions["OptimizeReference"] = "/OPT:REF"; })
            );

            //EnableCOMDATFolding
            //    Default                                 EnableCOMDATFolding="0"
            //    DoNotRemoveRedundantCOMDATs             EnableCOMDATFolding="1"                 /OPT:NOICF
            //    RemoveRedundantCOMDATs                  EnableCOMDATFolding="2"                 /OPT:ICF
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.EnableCOMDATFolding.DoNotRemoveRedundantCOMDATs, () => { context.Options["EnableCOMDATFolding"] = "false"; context.CommandLineOptions["EnableCOMDATFolding"] = "/OPT:NOICF"; }),
            Options.Option(Options.Vc.Linker.EnableCOMDATFolding.RemoveRedundantCOMDATs, () => { context.Options["EnableCOMDATFolding"] = "true"; context.CommandLineOptions["EnableCOMDATFolding"] = "/OPT:ICF"; })
            );

            //FixedBaseAddress
            //    Default                                 FixedBaseAddress="0"
            //    Enable                                  FixedBaseAddress="1"                  /FIXED
            //    Disable                                 FixedBaseAddress="2"                  /FIXED:NO
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.FixedBaseAddress.Default, () => { context.Options["FixedBaseAddress"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["FixedBaseAddress"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.FixedBaseAddress.Enable, () => { context.Options["FixedBaseAddress"] = "true"; context.CommandLineOptions["FixedBaseAddress"] = "/FIXED"; }),
            Options.Option(Options.Vc.Linker.FixedBaseAddress.Disable, () => { context.Options["FixedBaseAddress"] = "false"; context.CommandLineOptions["FixedBaseAddress"] = "/FIXED:NO"; })
            );

            //GenerateWindowsMetadata
            //    Default                                 GenerateWindowsMetadata="0"
            //    Enable                                  GenerateWindowsMetadata="1"                  /WINMD
            //    Disable                                 GenerateWindowsMetadata="2"                  /WINMD:NO
            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.GenerateWindowsMetadata.Default, () =>
            {
                context.Options["GenerateWindowsMetadata"] = FileGeneratorUtilities.RemoveLineTag;
                context.Options["WindowsMetadataFile"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["GenerateWindowsMetadata"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["WindowsMetadataFile"] = FileGeneratorUtilities.RemoveLineTag;
            }),
            Options.Option(Options.Vc.Linker.GenerateWindowsMetadata.Enable, () =>
            {
                context.Options["GenerateWindowsMetadata"] = "true";
                string windowsMetadataFile = @"$(OutDir)\$(RootNamespace).winmd";
                context.Options["WindowsMetadataFile"] = windowsMetadataFile;
                context.CommandLineOptions["GenerateWindowsMetadata"] = "/WINMD";
                context.CommandLineOptions["WindowsMetadataFile"] = @"/WINMDFILE:""" + windowsMetadataFile + @"""";
            }),
            Options.Option(Options.Vc.Linker.GenerateWindowsMetadata.Disable, () =>
            {
                context.Options["GenerateWindowsMetadata"] = "false";
                context.Options["WindowsMetadataFile"] = FileGeneratorUtilities.RemoveLineTag;
                context.CommandLineOptions["GenerateWindowsMetadata"] = "/WINMD:NO";
                context.CommandLineOptions["WindowsMetadataFile"] = FileGeneratorUtilities.RemoveLineTag;
            })
            );

            //LinkTimeCodeGeneration
            //    Default                                 LinkTimeCodeGeneration="0"
            //    UseLinkTimeCodeGeneration               LinkTimeCodeGeneration="1"              /ltcg
            //    ProfileGuidedOptimizationInstrument     LinkTimeCodeGeneration="2"              /ltcg:pginstrument
            //    ProfileGuidedOptimizationOptimize       LinkTimeCodeGeneration="3"              /ltcg:pgoptimize
            //    ProfileGuidedOptimizationUpdate         LinkTimeCodeGeneration="4"              /ltcg:pgupdate
            bool profileGuideOptimization = false;

            if (context.Configuration.Output == Project.Configuration.OutputType.Lib)
            {
                context.SelectOption
                (
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.Default, () => { context.Options["LinkTimeCodeGeneration"] = "false"; context.CommandLineOptions["LinkTimeCodeGeneration"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.UseLinkTimeCodeGeneration, () => { context.Options["LinkTimeCodeGeneration"] = "true"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.UseFastLinkTimeCodeGeneration, () => { context.Options["LinkTimeCodeGeneration"] = "true"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationInstrument, () => { context.Options["LinkTimeCodeGeneration"] = "true"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationOptimize, () => { context.Options["LinkTimeCodeGeneration"] = "true"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationUpdate, () => { context.Options["LinkTimeCodeGeneration"] = "true"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; })
                );
            }
            else
            {
                context.SelectOption
                (
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.Default, () => { context.Options["LinkTimeCodeGeneration"] = "Default"; context.CommandLineOptions["LinkTimeCodeGeneration"] = FileGeneratorUtilities.RemoveLineTag; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.UseFastLinkTimeCodeGeneration, () => { context.Options["LinkTimeCodeGeneration"] = "UseFastLinkTimeCodeGeneration"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG:incremental"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.UseLinkTimeCodeGeneration, () => { context.Options["LinkTimeCodeGeneration"] = "UseLinkTimeCodeGeneration"; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationInstrument, () => { context.Options["LinkTimeCodeGeneration"] = "PGInstrument"; profileGuideOptimization = true; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG:PGInstrument"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationOptimize, () => { context.Options["LinkTimeCodeGeneration"] = "PGOptimization"; profileGuideOptimization = true; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG:PGOptimize"; }),
                Options.Option(Options.Vc.Linker.LinkTimeCodeGeneration.ProfileGuidedOptimizationUpdate, () => { context.Options["LinkTimeCodeGeneration"] = "PGUpdate"; profileGuideOptimization = true; context.CommandLineOptions["LinkTimeCodeGeneration"] = "/LTCG:PGUpdate"; })
                );
            }


            if (profileGuideOptimization)
            {
                string profileGuidedDatabase = optionsContext.OutputDirectoryRelative + Util.WindowsSeparator + context.Configuration.TargetFileFullName + ".pgd";
                context.Options["ProfileGuidedDatabase"] = profileGuidedDatabase;
                context.CommandLineOptions["ProfileGuidedDatabase"] = @"/PGD:""" + profileGuidedDatabase + @"""";
            }
            else
            {
                context.Options["ProfileGuidedDatabase"] = "";
                context.CommandLineOptions["ProfileGuidedDatabase"] = FileGeneratorUtilities.RemoveLineTag;
            }

            // FunctionOrder
            // FunctionOrder="@..\path_to\order.txt"             /ORDER:"@..\path_to\order.txt"
            Options.Vc.Linker.FunctionOrder fctOrder = Options.GetObject<Options.Vc.Linker.FunctionOrder>(context.Configuration);
            context.Options["FunctionOrder"] = (fctOrder != null) ? fctOrder.Order : FileGeneratorUtilities.RemoveLineTag;
            context.CommandLineOptions["FunctionOrder"] = (fctOrder != null) ? @"/ORDER:@""" + fctOrder.Order + @"""" : FileGeneratorUtilities.RemoveLineTag;

            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.ForceFileOutput.Default, () => { context.Options["ForceFileOutput"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["ForceFileOutput"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.ForceFileOutput.Enable, () => { context.Options["ForceFileOutput"] = "Enabled"; context.CommandLineOptions["ForceFileOutput"] = "/FORCE"; }),
            Options.Option(Options.Vc.Linker.ForceFileOutput.MultiplyDefinedSymbolOnly, () => { context.Options["ForceFileOutput"] = "MultiplyDefinedSymbolOnly"; context.CommandLineOptions["ForceFileOutput"] = "/FORCE:MULTIPLE"; }),
            Options.Option(Options.Vc.Linker.ForceFileOutput.UndefinedSymbolOnly, () => { context.Options["ForceFileOutput"] = "UndefinedSymbolOnly"; context.CommandLineOptions["ForceFileOutput"] = "/FORCE:UNRESOLVED"; })
            );

            context.SelectOption
            (
            Options.Option(Options.Vc.Linker.CreateHotPatchableImage.Disable, () => { context.Options["LinkerCreateHotPatchableImage"] = FileGeneratorUtilities.RemoveLineTag; context.CommandLineOptions["LinkerCreateHotPatchableImage"] = FileGeneratorUtilities.RemoveLineTag; }),
            Options.Option(Options.Vc.Linker.CreateHotPatchableImage.Enable, () => { context.Options["LinkerCreateHotPatchableImage"] = "Enabled"; context.CommandLineOptions["LinkerCreateHotPatchableImage"] = "/FUNCTIONPADMIN"; }),
            Options.Option(Options.Vc.Linker.CreateHotPatchableImage.X86Image, () => { context.Options["LinkerCreateHotPatchableImage"] = "X86Image"; context.CommandLineOptions["LinkerCreateHotPatchableImage"] = "/FUNCTIONPADMIN:5"; }),
            Options.Option(Options.Vc.Linker.CreateHotPatchableImage.X64Image, () => { context.Options["LinkerCreateHotPatchableImage"] = "X64Image"; context.CommandLineOptions["LinkerCreateHotPatchableImage"] = "/FUNCTIONPADMIN:6"; }),
            Options.Option(Options.Vc.Linker.CreateHotPatchableImage.ItaniumImage, () => { context.Options["LinkerCreateHotPatchableImage"] = "ItaniumImage"; context.CommandLineOptions["LinkerCreateHotPatchableImage"] = "/FUNCTIONPADMIN:16"; })
            );

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

            // Target Machine
            optionsContext.PlatformVcxproj.SetupPlatformTargetOptions(context);
            optionsContext.PlatformVcxproj.SelectLinkerOptions(context);

            // Options.Vc.Librarian.AdditionalOptions
            context.Configuration.AdditionalLibrarianOptions.Sort();
            string additionalLibrarianOptions = context.Configuration.AdditionalLibrarianOptions.JoinStrings(" ").Trim();

            // Options.Vc.Linker.AdditionalOptions
            context.Configuration.AdditionalLinkerOptions.Sort();
            string linkerAdditionalOptions = context.Configuration.AdditionalLinkerOptions.JoinStrings(" ").Trim();

            Func<Strings, string> formatIgnoredWarnings = disabledWarnings =>
            {
                if (disabledWarnings.Count > 0)
                    return "/ignore:" + disabledWarnings.JoinStrings(",");
                return string.Empty;
            };

            // Treat Options.Vc.Librarian/Linker.DisableSpecificWarnings here because
            // they do not have a specific line in the vcxproj
            string ignoredLibWarnings = formatIgnoredWarnings(Options.GetStrings<Options.Vc.Librarian.DisableSpecificWarnings>(context.Configuration));
            if (!string.IsNullOrEmpty(ignoredLibWarnings))
            {
                if (additionalLibrarianOptions.Length > 0)
                    additionalLibrarianOptions += " ";
                additionalLibrarianOptions += ignoredLibWarnings;
            }

            string ignoredLinkerWarnings = formatIgnoredWarnings(Options.GetStrings<Options.Vc.Linker.DisableSpecificWarnings>(context.Configuration));
            if (!string.IsNullOrEmpty(ignoredLinkerWarnings))
            {
                if (linkerAdditionalOptions.Length > 0)
                    linkerAdditionalOptions += " ";
                linkerAdditionalOptions += ignoredLinkerWarnings;
            }

            context.Options["AdditionalLibrarianOptions"] = additionalLibrarianOptions.Length > 0 ? additionalLibrarianOptions : FileGeneratorUtilities.RemoveLineTag;
            context.Options["AdditionalLinkerOptions"] = linkerAdditionalOptions.Length > 0 ? linkerAdditionalOptions : FileGeneratorUtilities.RemoveLineTag;
        }