예제 #1
0
        static int Fix(ApplePlatform platform, string output)
        {
            var frameworks = Frameworks.GetFrameworks(platform, false).Values.Where(v => !v.Unavailable);
            var sb         = new StringBuilder();

#if NET
            sb.AppendLine("#if NET");
#else
            sb.AppendLine("#if !NET");
#endif
            sb.AppendLine("namespace ObjCRuntime {");
            sb.AppendLine("\tpublic static partial class Constants {");
            foreach (var grouped in frameworks.GroupBy(v => v.Version))
            {
                sb.AppendLine($"\t\t// {platform} {grouped.Key}");
                foreach (var fw in grouped.OrderBy(v => v.Name))
                {
                    sb.AppendLine($"\t\tpublic const string {fw.Namespace}Library = \"{fw.LibraryPath}\";");
                }
                sb.AppendLine();
            }
            sb.AppendLine("\t}");
            sb.AppendLine("}");
#if NET
            sb.AppendLine("#endif // NET");
#else
            sb.AppendLine("#endif // !NET");
#endif

            File.WriteAllText(output, sb.ToString());
            return(0);
        }
예제 #2
0
        public void Process(LinkContext context)
        {
            var profile = (Profile.Current as BaseProfile);

            AssemblyDefinition assembly;

            if (!context.TryGetLinkedAssembly(profile.ProductAssembly, out assembly))
            {
                return;
            }

            HashSet <string> namespaces = new HashSet <string> ();

            foreach (TypeDefinition type in assembly.MainModule.Types)
            {
                namespaces.Add(type.Namespace);
            }

            // Compute our map
            // there can be multiple namespaces for the same library
            var frameworks = Frameworks.GetFrameworks(((DerivedLinkContext)context).App.Platform, false);
            var map        = new Dictionary <string, List <string> > ();

            foreach (var fw in frameworks.Values)
            {
                if (!map.TryGetValue(fw.LibraryPath, out var list))
                {
                    map [fw.LibraryPath] = list = new List <string> ();
                }
                list.Add(fw.Namespace);
            }

            // clean NSObject from loading them

            var nsobject       = assembly.MainModule.GetType(Namespaces.Foundation + ".NSObject");
            var nsobject_cctor = nsobject.GetTypeConstructor();

            var instructions = nsobject_cctor.Body.Instructions;

            for (int i = 0; i < instructions.Count; i++)
            {
                Instruction ins = instructions [i];
                if (ins.OpCode.Code != Code.Ldstr)
                {
                    continue;
                }

                // To be safe we only remove the ones we know about *and*
                // only when we know the namespace is not being used by the app
                // Based on the list from xamcore/src/Foundation/NSObjectMac.cs
                bool remove_dlopen = false;

                if (map.TryGetValue(ins.Operand as string, out var targetNamespaces))
                {
                    remove_dlopen = !targetNamespaces.Any(v => namespaces.Contains(v));
                }
#if DEBUG
                else
                {
                    string libname = ins.Operand as string;
                    if (libname.StartsWith("/", StringComparison.Ordinal))
                    {
                        Console.WriteLine("Unprocessed library / namespace {0}", libname);
                    }
                }
#endif

                if (remove_dlopen)
                {
                    FieldDefinition f = Nop(ins);
                    if (f != null)
                    {
                        i += 3;
                        nsobject.Fields.Remove(f);
                    }
                }
            }
        }