bool Execute(DirectoryAssemblyResolver res)
        {
            // Put every assembly we'll need in the resolver
            foreach (var assembly in ResolvedAssemblies)
            {
                res.Load(Path.GetFullPath(assembly.ItemSpec));
            }

            var resolver = new AssemblyResolver(res.ToResolverCache());

            // Set up for linking
            var options = new LinkerOptions();

            options.MainAssembly     = res.GetAssembly(MainAssembly);
            options.OutputDirectory  = Path.GetFullPath(OutputDirectory);
            options.LinkSdkOnly      = string.Compare(LinkMode, "SdkOnly", true) == 0;
            options.LinkNone         = false;
            options.Resolver         = resolver;
            options.LinkDescriptions = LinkDescriptions.Select(item => Path.GetFullPath(item.ItemSpec)).ToArray();
            options.I18nAssemblies   = Linker.ParseI18nAssemblies(I18nAssemblies);
            if (!options.LinkSdkOnly)
            {
                options.RetainAssemblies = GetRetainAssemblies(res);
            }
            options.DumpDependencies          = DumpDependencies;
            options.HttpClientHandlerType     = HttpClientHandlerType;
            options.TlsProvider               = TlsProvider;
            options.AddKeepAlives             = AddKeepAlives;
            options.PreserveJniMarshalMethods = PreserveJniMarshalMethods;
            options.DeterministicOutput       = Deterministic;
            options.LinkResources             = LinkResources;

            var skiplist = new List <string> ();

            // Add LinkSkip options
            if (!string.IsNullOrWhiteSpace(LinkSkip))
            {
                skiplist.AddRange(LinkSkip.Split(',', ';'));
            }

            options.SkippedAssemblies = skiplist;

            if (EnableProguard)
            {
                options.ProguardConfiguration = ProguardConfiguration;
            }

            // Link!
            try {
                LinkContext link_context;
                Linker.Process(options, this, out link_context);

                foreach (var assembly in ResolvedAssemblies)
                {
                    var copysrc             = assembly.ItemSpec;
                    var filename            = Path.GetFileName(assembly.ItemSpec);
                    var assemblyDestination = Path.Combine(OutputDirectory, filename);

                    if (!MonoAndroidHelper.IsForceRetainedAssembly(filename))
                    {
                        continue;
                    }

                    MonoAndroidHelper.CopyAssemblyAndSymbols(copysrc, assemblyDestination);
                }
            } catch (ResolutionException ex) {
                Diagnostic.Error(2006, ex, Properties.Resources.XA2006, ex.Member, ex.Member.Module.Assembly, ex.Scope);
            }

            return(true);
        }
        public override bool RunTask()
        {
            if (SourceFiles.Length != DestinationFiles.Length)
            {
                throw new ArgumentException("source and destination count mismatch");
            }

            var readerParameters = new ReaderParameters {
                ReadSymbols = true,
            };
            var writerParameters = new WriterParameters {
                DeterministicMvid = Deterministic,
            };

            using (var resolver = new DirectoryAssemblyResolver(this.CreateTaskLogger(), loadDebugSymbols: true, loadReaderParameters: readerParameters)) {
                // Add SearchDirectories with ResolvedAssemblies
                foreach (var assembly in ResolvedAssemblies)
                {
                    var path = Path.GetFullPath(Path.GetDirectoryName(assembly.ItemSpec));
                    if (!resolver.SearchDirectories.Contains(path))
                    {
                        resolver.SearchDirectories.Add(path);
                    }
                }

                // Set up the FixAbstractMethodsStep
                var step1 = new FixAbstractMethodsStep(resolver, new TypeDefinitionCache(), Log);
                // Set up the AddKeepAlivesStep
                var step2 = new MonoDroid.Tuner.AddKeepAlivesStep(new TypeDefinitionCache());
                for (int i = 0; i < SourceFiles.Length; i++)
                {
                    var source      = SourceFiles [i];
                    var destination = DestinationFiles [i];
                    AssemblyDefinition assemblyDefinition = null;

                    var assemblyName = Path.GetFileNameWithoutExtension(source.ItemSpec);
                    if (!MTProfile.IsSdkAssembly(assemblyName) && !MTProfile.IsProductAssembly(assemblyName))
                    {
                        assemblyDefinition = resolver.GetAssembly(source.ItemSpec);
                        step1.CheckAppDomainUsage(assemblyDefinition, (string msg) => Log.LogMessageFromText(msg, MessageImportance.High));
                    }

                    // Only run the step on "MonoAndroid" assemblies
                    if (MonoAndroidHelper.IsMonoAndroidAssembly(source) && !MonoAndroidHelper.IsSharedRuntimeAssembly(source.ItemSpec))
                    {
                        if (assemblyDefinition == null)
                        {
                            assemblyDefinition = resolver.GetAssembly(source.ItemSpec);
                        }

                        if (step1.FixAbstractMethods(assemblyDefinition) ||
                            (AddKeepAlives && step2.AddKeepAlives(assemblyDefinition)))
                        {
                            Log.LogDebugMessage($"Saving modified assembly: {destination.ItemSpec}");
                            writerParameters.WriteSymbols = assemblyDefinition.MainModule.HasSymbols;
                            assemblyDefinition.Write(destination.ItemSpec, writerParameters);
                            continue;
                        }
                    }

                    if (MonoAndroidHelper.CopyAssemblyAndSymbols(source.ItemSpec, destination.ItemSpec))
                    {
                        Log.LogDebugMessage($"Copied: {destination.ItemSpec}");
                    }
                    else
                    {
                        Log.LogDebugMessage($"Skipped unchanged file: {destination.ItemSpec}");

                        // NOTE: We still need to update the timestamp on this file, or this target would run again
                        File.SetLastWriteTimeUtc(destination.ItemSpec, DateTime.UtcNow);
                    }
                }
            }

            return(!Log.HasLoggedErrors);
        }
Example #3
0
        public override bool RunTask()
        {
            if (SourceFiles.Length != DestinationFiles.Length)
            {
                throw new ArgumentException("source and destination count mismatch");
            }

            var readerParameters = new ReaderParameters {
                ReadSymbols = true,
            };
            var writerParameters = new WriterParameters {
                DeterministicMvid = Deterministic,
            };

            using (var resolver = new DirectoryAssemblyResolver(this.CreateTaskLogger(), loadDebugSymbols: true, loadReaderParameters: readerParameters)) {
                // Add SearchDirectories with ResolvedAssemblies
                foreach (var assembly in ResolvedAssemblies)
                {
                    var path = Path.GetFullPath(Path.GetDirectoryName(assembly.ItemSpec));
                    if (!resolver.SearchDirectories.Contains(path))
                    {
                        resolver.SearchDirectories.Add(path);
                    }
                }

                // Run the FixAbstractMethodsStep
                var step = new FixAbstractMethodsStep(resolver, Log);
                for (int i = 0; i < SourceFiles.Length; i++)
                {
                    var source      = SourceFiles [i];
                    var destination = DestinationFiles [i];

                    // Only run the step on "MonoAndroid" assemblies
                    if (MonoAndroidHelper.IsMonoAndroidAssembly(source) && !MonoAndroidHelper.IsSharedRuntimeAssembly(source.ItemSpec))
                    {
                        var assemblyDefinition = resolver.GetAssembly(source.ItemSpec);
                        if (step.FixAbstractMethods(assemblyDefinition))
                        {
                            Log.LogDebugMessage($"Saving modified assembly: {destination.ItemSpec}");
                            writerParameters.WriteSymbols = assemblyDefinition.MainModule.HasSymbols;
                            assemblyDefinition.Write(destination.ItemSpec, writerParameters);
                            continue;
                        }
                    }

                    if (MonoAndroidHelper.CopyAssemblyAndSymbols(source.ItemSpec, destination.ItemSpec))
                    {
                        Log.LogDebugMessage($"Copied: {destination.ItemSpec}");
                    }
                    else
                    {
                        Log.LogDebugMessage($"Skipped unchanged file: {destination.ItemSpec}");

                        // NOTE: We still need to update the timestamp on this file, or this target would run again
                        File.SetLastWriteTimeUtc(destination.ItemSpec, DateTime.UtcNow);
                    }
                }
            }

            return(!Log.HasLoggedErrors);
        }
Example #4
0
        bool Execute(DirectoryAssemblyResolver res)
        {
            // Put every assembly we'll need in the resolver
            foreach (var assembly in ResolvedAssemblies)
            {
                res.Load(Path.GetFullPath(assembly.ItemSpec));
            }

            var resolver = new AssemblyResolver(res.ToResolverCache());

            // Set up for linking
            var options = new LinkerOptions();

            options.MainAssembly     = res.GetAssembly(MainAssembly);
            options.OutputDirectory  = Path.GetFullPath(OutputDirectory);
            options.LinkSdkOnly      = string.Compare(LinkMode, "SdkOnly", true) == 0;
            options.LinkNone         = false;
            options.Resolver         = resolver;
            options.LinkDescriptions = LinkDescriptions.Select(item => Path.GetFullPath(item.ItemSpec)).ToArray();
            options.I18nAssemblies   = Linker.ParseI18nAssemblies(I18nAssemblies);
            if (!options.LinkSdkOnly)
            {
                options.RetainAssemblies = GetRetainAssemblies(res);
            }
            options.DumpDependencies          = DumpDependencies;
            options.HttpClientHandlerType     = HttpClientHandlerType;
            options.TlsProvider               = TlsProvider;
            options.PreserveJniMarshalMethods = PreserveJniMarshalMethods;
            options.DeterministicOutput       = Deterministic;

            var skiplist = new List <string> ();

            if (string.Compare(UseSharedRuntime, "true", true) == 0)
            {
                skiplist.AddRange(Profile.SharedRuntimeAssemblies.Where(a => a.EndsWith(".dll")).Select(a => Path.GetFileNameWithoutExtension(a)));
            }

            // Add LinkSkip options
            if (!string.IsNullOrWhiteSpace(LinkSkip))
            {
                skiplist.AddRange(LinkSkip.Split(',', ';'));
            }

            options.SkippedAssemblies = skiplist;

            if (EnableProguard)
            {
                options.ProguardConfiguration = ProguardConfiguration;
            }

            // Link!
            try {
                LinkContext link_context;
                Linker.Process(options, this, out link_context);

                foreach (var assembly in ResolvedAssemblies)
                {
                    var copysrc             = assembly.ItemSpec;
                    var filename            = Path.GetFileName(assembly.ItemSpec);
                    var assemblyDestination = Path.Combine(OutputDirectory, filename);

                    if (!MonoAndroidHelper.IsForceRetainedAssembly(filename))
                    {
                        continue;
                    }

                    MonoAndroidHelper.CopyAssemblyAndSymbols(copysrc, assemblyDestination);
                }
            } catch (ResolutionException ex) {
                Diagnostic.Error(2006, ex, "Could not resolve reference to '{0}' (defined in assembly '{1}') with scope '{2}'. When the scope is different from the defining assembly, it usually means that the type is forwarded.", ex.Member, ex.Member.Module.Assembly, ex.Scope);
            }

            return(true);
        }