void Run() { Pipeline p = GetStandardPipeline(); LinkContext context = GetDefaultContext(p); I18nAssemblies assemblies = I18nAssemblies.All; var custom_steps = new List <string> (); bool resolver = false; while (HaveMoreTokens()) { string token = GetParam(); if (token.Length < 2) { Usage("Option is too short"); } if (!(token [0] == '-' || token [1] == '/')) { Usage("Expecting an option, got instead: " + token); } if (token [0] == '-' && token [1] == '-') { if (token.Length < 3) { Usage("Option is too short"); } switch (token [2]) { case 'v': Version(); break; case 'a': About(); break; default: Usage(null); break; } } switch (token [1]) { case 'd': { DirectoryInfo info = new DirectoryInfo(GetParam()); context.Resolver.AddSearchDirectory(info.FullName); break; } case 'o': context.OutputDirectory = GetParam(); break; case 'c': context.CoreAction = ParseAssemblyAction(GetParam()); break; case 'p': AssemblyAction action = ParseAssemblyAction(GetParam()); context.Actions [GetParam()] = action; break; case 's': custom_steps.Add(GetParam()); break; case 't': context.KeepTypeForwarderOnlyAssemblies = true; break; case 'x': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file))); } resolver = true; break; case 'r': case 'a': var rootVisibility = (token[1] == 'r') ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily : ResolveFromAssemblyStep.RootVisibility.Any; foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility)); } resolver = true; break; case 'i': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file))); } resolver = true; break; case 'l': assemblies = ParseI18n(GetParam()); break; case 'm': context.SetParameter(GetParam(), GetParam()); break; case 'b': context.LinkSymbols = bool.Parse(GetParam()); break; case 'g': if (!bool.Parse(GetParam())) { p.RemoveStep(typeof(RegenerateGuidStep)); } break; case 'v': context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam()); break; default: Usage("Unknown option: `" + token [1] + "'"); break; } } if (!resolver) { Usage("No resolver was created (use -x, -a or -i)"); } foreach (string custom_step in custom_steps) { AddCustomStep(p, custom_step); } p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies)); p.Process(context); }
public bool Run(ILogger customLogger = null) { Pipeline p = GetStandardPipeline(); using (LinkContext context = GetDefaultContext(p)) { if (customLogger != null) { context.Logger = customLogger; } #if !FEATURE_ILLINK I18nAssemblies assemblies = I18nAssemblies.All; #endif var custom_steps = new List <string> (); var excluded_features = new HashSet <string> (StringComparer.Ordinal); var disabled_optimizations = new HashSet <string> (StringComparer.Ordinal); var enabled_optimizations = new HashSet <string> (StringComparer.Ordinal); bool dumpDependencies = false; string dependenciesFileName = null; bool ignoreDescriptors = false; bool removeCAS = true; bool new_mvid_used = false; bool deterministic_used = false; bool resolver = false; while (arguments.Count > 0) { string token = arguments.Dequeue(); if (token.Length < 2) { ErrorUnrecognizedOption(token); return(false); } // // Handling of --value like options // if (token [0] == '-' && token [1] == '-') { switch (token) { case "--skip-unresolved": if (!GetBoolParam(token, l => context.IgnoreUnresolved = context.Resolver.IgnoreUnresolved = l)) { return(false); } continue; case "--verbose": context.LogMessages = true; continue; case "--dependencies-file": if (!GetStringParam(token, l => dependenciesFileName = l)) { return(false); } continue; case "--dump-dependencies": dumpDependencies = true; continue; case "--reduced-tracing": if (!GetBoolParam(token, l => context.EnableReducedTracing = l)) { return(false); } continue; case "--used-attrs-only": if (!GetBoolParam(token, l => context.KeepUsedAttributeTypesOnly = l)) { return(false); } continue; case "--strip-security": if (!GetBoolParam(token, l => removeCAS = l)) { return(false); } continue; case "--strip-resources": if (!GetBoolParam(token, l => context.StripResources = l)) { return(false); } continue; case "--substitutions": if (arguments.Count < 1) { ErrorMissingArgument(token); return(false); } if (!GetStringParam(token, l => context.AddSubstitutionFile(l))) { return(false); } continue; case "--exclude-feature": if (arguments.Count < 1) { ErrorMissingArgument(token); return(false); } if (!GetStringParam(token, l => { foreach (var feature in l.Split(',')) { if (!excluded_features.Contains(feature)) { excluded_features.Add(feature); } } })) { return(false); } continue; case "--explicit-reflection": if (!GetBoolParam(token, l => context.AddReflectionAnnotations = l)) { return(false); } continue; case "--custom-step": if (!GetStringParam(token, l => custom_steps.Add(l))) { return(false); } continue; case "--keep-facades": if (!GetBoolParam(token, l => context.KeepTypeForwarderOnlyAssemblies = l)) { return(false); } continue; case "--keep-dep-attributes": if (!GetBoolParam(token, l => context.KeepDependencyAttributes = l)) { return(false); } continue; case "--ignore-descriptors": if (!GetBoolParam(token, l => ignoreDescriptors = l)) { return(false); } continue; case "--disable-opt": if (!GetStringParam(token, l => { var opt = l.ToLowerInvariant(); if (!disabled_optimizations.Contains(opt)) { disabled_optimizations.Add(opt); } })) { return(false); } continue; case "--enable-opt": if (!GetStringParam(token, l => { var opt = l.ToLowerInvariant(); if (!enabled_optimizations.Contains(opt)) { enabled_optimizations.Add(opt); } })) { return(false); } continue; case "--new-mvid": // // This is not same as --deterministic which calculates MVID // from stable assembly content. This option creates a new random // mvid or uses mvid of the source assembly. // if (!GetBoolParam(token, l => { if (!l) { p.RemoveStep(typeof(RegenerateGuidStep)); } })) { return(false); } new_mvid_used = true; continue; case "--deterministic": if (!GetBoolParam(token, l => context.DeterministicOutput = l)) { return(false); } deterministic_used = true; continue; case "--output-assemblylist": if (!GetStringParam(token, l => context.AssemblyListFile = l)) { return(false); } continue; case "--version": Version(); return(true); case "--about": About(); return(true); } } if (token [0] == '-' || token [1] == '/') { switch (token.Substring(1)) { case "d": if (!GetStringParam(token, l => { DirectoryInfo info = new DirectoryInfo(l); context.Resolver.AddSearchDirectory(info.FullName); })) { return(false); } continue; case "o": case "out": if (!GetStringParam(token, l => context.OutputDirectory = l)) { return(false); } continue; case "c": if (!GetStringParam(token, l => context.CoreAction = ParseAssemblyAction(l))) { return(false); } continue; case "u": if (!GetStringParam(token, l => context.UserAction = ParseAssemblyAction(l))) { return(false); } continue; case "p": if (arguments.Count < 2) { ErrorMissingArgument(token); return(false); } AssemblyAction action = ParseAssemblyAction(arguments.Dequeue()); context.Actions [arguments.Dequeue()] = action; continue; case "t": context.KeepTypeForwarderOnlyAssemblies = true; continue; case "x": if (!GetStringParam(token, l => { foreach (string file in GetFiles(l)) { p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file))); } })) { return(false); } resolver = true; continue; case "r": case "a": if (!GetStringParam(token, l => { var rootVisibility = (token [1] == 'r') ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily : ResolveFromAssemblyStep.RootVisibility.Any; foreach (string file in GetFiles(l)) { p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility)); } })) { return(false); } resolver = true; continue; #if !FEATURE_ILLINK case "i": if (!GetStringParam(token, l => { foreach (string file in GetFiles(l)) { p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file))); } })) { return(false); } resolver = true; continue; case "l": if (!GetStringParam(token, l => assemblies = ParseI18n(l))) { return(false); } continue; #endif case "m": if (arguments.Count < 2) { ErrorMissingArgument(token); return(false); } context.SetParameter(arguments.Dequeue(), arguments.Dequeue()); continue; case "b": if (!GetBoolParam(token, l => context.LinkSymbols = l)) { return(false); } continue; case "g": if (!GetBoolParam(token, l => context.DeterministicOutput = !l)) { return(false); } continue; case "z": if (!GetBoolParam(token, l => ignoreDescriptors = !l)) { return(false); } continue; case "v": if (!GetBoolParam(token, l => context.KeepMembersForDebugger = l)) { return(false); } continue; case "?": case "help": Usage(); return(true); case "reference": if (!GetStringParam(token, l => context.Resolver.AddReferenceAssembly(l))) { return(false); } continue; } } ErrorUnrecognizedOption(token); return(false); } if (!resolver) { Console.WriteLine($"No files to link were specified. Use one of '{resolvers}' options"); return(false); } if (new_mvid_used && deterministic_used) { Console.WriteLine($"Options '--new-mvid' and '--deterministic' cannot be used at the same time"); return(false); } if (dumpDependencies) { context.Tracer.AddRecorder(new XmlDependencyRecorder(context, dependenciesFileName)); } if (disabled_optimizations.Count > 0) { foreach (var item in disabled_optimizations) { switch (item) { case "beforefieldinit": context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit; break; case "overrideremoval": context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval; break; case "unreachablebodies": context.DisabledOptimizations |= CodeOptimizations.UnreachableBodies; break; case "unusedinterfaces": context.DisabledOptimizations |= CodeOptimizations.UnusedInterfaces; break; case "ipconstprop": context.DisabledOptimizations |= CodeOptimizations.IPConstantPropagation; break; } } } if (enabled_optimizations.Count > 0) { foreach (var item in enabled_optimizations) { switch (item) { case "unreachablebodies": context.DisabledOptimizations &= ~CodeOptimizations.UnreachableBodies; break; case "clearinitlocals": context.DisabledOptimizations &= ~CodeOptimizations.ClearInitLocals; break; case "ipconstprop": context.DisabledOptimizations &= ~CodeOptimizations.IPConstantPropagation; break; } } } // // Modify the default pipeline // if (ignoreDescriptors) { p.RemoveStep(typeof(BlacklistStep)); } if (context.DeterministicOutput) { p.RemoveStep(typeof(RegenerateGuidStep)); } if (context.AddReflectionAnnotations) { p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep()); } #if !FEATURE_ILLINK p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies)); if (assemblies != I18nAssemblies.None) { p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies)); } #endif if (_needAddBypassNGenStep) { p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep()); } p.AddStepBefore(typeof(MarkStep), new BodySubstituterStep()); if (removeCAS) { p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep()); } if (excluded_features.Count > 0) { p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep() { FeatureCOM = excluded_features.Contains("com"), FeatureETW = excluded_features.Contains("etw"), FeatureSRE = excluded_features.Contains("sre"), FeatureGlobalization = excluded_features.Contains("globalization") }); var excluded = new string [excluded_features.Count]; excluded_features.CopyTo(excluded); context.ExcludedFeatures = excluded; } p.AddStepBefore(typeof(MarkStep), new RemoveUnreachableBlocksStep()); if (context.IsOptimizationEnabled(CodeOptimizations.ClearInitLocals)) { p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep()); } // // Pipeline setup with all steps enabled // // LoadReferencesStep // BlacklistStep [optional] // PreserveDependencyLookupStep // TypeMapStep // BodySubstituterStep [optional] // RemoveSecurityStep [optional] // RemoveFeaturesStep [optional] // RemoveUnreachableBlocksStep [optional] // MarkStep // ReflectionBlockedStep [optional] // SweepStep // AddBypassNGenStep [optional] // CodeRewriterStep // CleanStep // RegenerateGuidStep [optional] // ClearInitLocalsStep [optional] // OutputStep // foreach (string custom_step in custom_steps) { if (!AddCustomStep(p, custom_step)) { return(false); } } PreProcessPipeline(p); try { p.Process(context); } finally { context.Tracer.Finish(); } return(true); } }
public void Run(ILogger customLogger = null) { Pipeline p = GetStandardPipeline(); using (LinkContext context = GetDefaultContext(p)) { if (customLogger != null) { context.Logger = customLogger; } I18nAssemblies assemblies = I18nAssemblies.All; var custom_steps = new List <string> (); var excluded_features = new HashSet <string> (StringComparer.Ordinal); var disabled_optimizations = new HashSet <string> (StringComparer.Ordinal); bool dumpDependencies = false; bool ignoreDescriptors = false; bool removeCAS = true; bool resolver = false; while (HaveMoreTokens()) { string token = GetParam(); if (token.Length < 2) { Usage("Option is too short"); } if (!(token [0] == '-' || token [1] == '/')) { Usage("Expecting an option, got instead: " + token); } if (token [0] == '-' && token [1] == '-') { if (token.Length < 3) { Usage("Option is too short"); } switch (token) { case "--skip-unresolved": bool ignoreUnresolved = bool.Parse(GetParam()); context.IgnoreUnresolved = ignoreUnresolved; context.Resolver.IgnoreUnresolved = ignoreUnresolved; continue; case "--verbose": context.LogMessages = true; continue; case "--dependencies-file": context.Tracer.DependenciesFileName = GetParam(); continue; case "--dump-dependencies": dumpDependencies = true; continue; case "--reduced-tracing": context.EnableReducedTracing = bool.Parse(GetParam()); continue; case "--used-attrs-only": context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam()); continue; case "--strip-security": removeCAS = bool.Parse(GetParam()); continue; case "--strip-resources": context.StripResources = bool.Parse(GetParam()); continue; case "--exclude-feature": var name = GetParam(); foreach (var feature in name.Split(',')) { if (!excluded_features.Contains(feature)) { excluded_features.Add(feature); } } continue; case "--custom-step": custom_steps.Add(GetParam()); continue; case "--keep-facades": context.KeepTypeForwarderOnlyAssemblies = bool.Parse(GetParam()); continue; case "--ignore-descriptors": ignoreDescriptors = bool.Parse(GetParam()); continue; case "--disable-opt": var opt = GetParam().ToLower(); if (!disabled_optimizations.Contains(opt)) { disabled_optimizations.Add(opt); } continue; } switch (token [2]) { case 'v': Version(); break; case 'a': About(); break; default: Usage(null); break; } } switch (token [1]) { case 'd': DirectoryInfo info = new DirectoryInfo(GetParam()); context.Resolver.AddSearchDirectory(info.FullName); break; case 'o': context.OutputDirectory = GetParam(); break; case 'c': context.CoreAction = ParseAssemblyAction(GetParam()); break; case 'u': context.UserAction = ParseAssemblyAction(GetParam()); break; case 'p': AssemblyAction action = ParseAssemblyAction(GetParam()); context.Actions [GetParam()] = action; break; case 't': context.KeepTypeForwarderOnlyAssemblies = true; break; case 'x': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file))); } resolver = true; break; case 'r': case 'a': var rootVisibility = (token [1] == 'r') ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily : ResolveFromAssemblyStep.RootVisibility.Any; foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility)); } resolver = true; break; case 'i': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file))); } resolver = true; break; case 'l': assemblies = ParseI18n(GetParam()); break; case 'm': context.SetParameter(GetParam(), GetParam()); break; case 'b': context.LinkSymbols = bool.Parse(GetParam()); break; case 'g': if (!bool.Parse(GetParam())) { p.RemoveStep(typeof(RegenerateGuidStep)); } break; case 'z': ignoreDescriptors = !bool.Parse(GetParam()); break; case 'v': context.KeepMembersForDebugger = bool.Parse(GetParam()); break; default: Usage("Unknown option: `" + token [1] + "'"); break; } } if (!resolver) { Usage("No resolver was created (use -x, -a or -i)"); } if (ignoreDescriptors) { p.RemoveStep(typeof(BlacklistStep)); } if (dumpDependencies) { context.Tracer.Start(); } foreach (string custom_step in custom_steps) { AddCustomStep(p, custom_step); } p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies)); if (_needAddBypassNGenStep) { p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep()); } if (assemblies != I18nAssemblies.None) { p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies)); } if (removeCAS) { p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep()); } if (excluded_features.Count > 0) { p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep() { FeatureCOM = excluded_features.Contains("com"), FeatureETW = excluded_features.Contains("etw"), FeatureGlobalization = excluded_features.Contains("globalization") }); var excluded = new string [excluded_features.Count]; excluded_features.CopyTo(excluded); context.ExcludedFeatures = excluded; } if (disabled_optimizations.Count > 0) { foreach (var item in disabled_optimizations) { switch (item) { case "beforefieldinit": context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit; break; case "overrideremoval": context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval; break; } } } PreProcessPipeline(p); try { p.Process(context); } finally { if (dumpDependencies) { context.Tracer.Finish(); } } } }
public void Run(ILogger customLogger = null) { Pipeline p = GetStandardPipeline(); using (LinkContext context = GetDefaultContext(p)) { if (customLogger != null) { context.Logger = customLogger; } I18nAssemblies assemblies = I18nAssemblies.All; var custom_steps = new List <string> (); bool dumpDependencies = false; bool resolver = false; while (HaveMoreTokens()) { string token = GetParam(); if (token.Length < 2) { Usage("Option is too short"); } if (!(token [0] == '-' || token [1] == '/')) { Usage("Expecting an option, got instead: " + token); } if (token [0] == '-' && token [1] == '-') { if (token.Length < 3) { Usage("Option is too short"); } if (token == "--skip-unresolved") { bool ignoreUnresolved = bool.Parse(GetParam()); context.IgnoreUnresolved = ignoreUnresolved; context.Resolver.IgnoreUnresolved = ignoreUnresolved; continue; } if (token == "--verbose") { context.LogMessages = true; continue; } if (token == "--dependencies-file") { context.Tracer.DependenciesFileName = GetParam(); continue; } if (token == "--dump-dependencies") { dumpDependencies = true; continue; } if (token == "--reduced-tracing") { context.EnableReducedTracing = bool.Parse(GetParam()); continue; } if (token == "--used-attrs-only") { context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam()); continue; } if (token == "--strip-security") { if (bool.Parse(GetParam())) { p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep()); } continue; } if (token == "--strip-resources") { context.StripResources = bool.Parse(GetParam()); continue; } switch (token [2]) { case 'v': Version(); break; case 'a': About(); break; default: Usage(null); break; } } switch (token [1]) { case 'd': { DirectoryInfo info = new DirectoryInfo(GetParam()); context.Resolver.AddSearchDirectory(info.FullName); break; } case 'o': context.OutputDirectory = GetParam(); break; case 'c': context.CoreAction = ParseAssemblyAction(GetParam()); break; case 'u': context.UserAction = ParseAssemblyAction(GetParam()); break; case 'p': AssemblyAction action = ParseAssemblyAction(GetParam()); context.Actions [GetParam()] = action; break; case 's': custom_steps.Add(GetParam()); break; case 't': context.KeepTypeForwarderOnlyAssemblies = true; break; case 'x': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file))); } resolver = true; break; case 'r': case 'a': var rootVisibility = (token [1] == 'r') ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily : ResolveFromAssemblyStep.RootVisibility.Any; foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility)); } resolver = true; break; case 'i': foreach (string file in GetFiles(GetParam())) { p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file))); } resolver = true; break; case 'l': assemblies = ParseI18n(GetParam()); break; case 'm': context.SetParameter(GetParam(), GetParam()); break; case 'b': context.LinkSymbols = bool.Parse(GetParam()); break; case 'g': if (!bool.Parse(GetParam())) { p.RemoveStep(typeof(RegenerateGuidStep)); } break; case 'z': if (!bool.Parse(GetParam())) { p.RemoveStep(typeof(BlacklistStep)); } break; case 'v': context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam()); break; default: Usage("Unknown option: `" + token [1] + "'"); break; } } if (!resolver) { Usage("No resolver was created (use -x, -a or -i)"); } if (dumpDependencies) { context.Tracer.Start(); } foreach (string custom_step in custom_steps) { AddCustomStep(p, custom_step); } p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies)); if (_needAddBypassNGenStep) { p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep()); } p.Process(context); } }