Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
                var            enabled_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 "--substitutions":
                            context.AddSubstitutionFile(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 "--explicit-reflection":
                            context.AddReflectionAnnotations = true;
                            continue;

                        case "--custom-step":
                            custom_steps.Add(GetParam());
                            continue;

                        case "--keep-facades":
                            context.KeepTypeForwarderOnlyAssemblies = bool.Parse(GetParam());
                            continue;

                        case "--keep-dep-attributes":
                            context.KeepDependencyAttributes = 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;

                        case "--enable-opt":
                            opt = GetParam().ToLower();
                            if (!enabled_optimizations.Contains(opt))
                            {
                                enabled_optimizations.Add(opt);
                            }

                            continue;

                        case "--new-mvid":
                            if (!bool.Parse(GetParam()))
                            {
                                p.RemoveStep(typeof(RegenerateGuidStep));
                            }
                            continue;

                        case "--deterministic":
                            context.DeterministicOutput = true;
                            p.RemoveStep(typeof(RegenerateGuidStep));
                            continue;

                        case "--output-assemblylist":
                            context.AssemblyListFile = GetParam();
                            continue;
                        }

                        switch (token [2])
                        {
                        case 'v':
                            Version();
                            break;

                        case 'a':
                            About();
                            break;

                        default:
                            Usage(null);
                            break;
                        }
                    }

                    // Ensure this does not conflict with '-r' below.
                    if (token == "-reference")
                    {
                        context.Resolver.AddReferenceAssembly(GetParam());
                        continue;
                    }

                    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);
                }

                if (context.AddReflectionAnnotations)
                {
                    p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep());
                }

                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));
                }

                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 (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;
                        }
                    }
                }

                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;
                        }
                    }
                }

                if (context.IsOptimizationEnabled(CodeOptimizations.ClearInitLocals))
                {
                    p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep());
                }

                PreProcessPipeline(p);

                try {
                    p.Process(context);
                }
                finally {
                    if (dumpDependencies)
                    {
                        context.Tracer.Finish();
                    }
                }
            }
        }