Пример #1
0
        IEnumerable <NativeReferenceMetadata> ReadManifest(string manifestPath)
        {
            XmlDocument document = new XmlDocument();

            document.LoadWithoutNetworkAccess(manifestPath);

            foreach (XmlNode referenceNode in document.GetElementsByTagName("NativeReference"))
            {
                NativeReferenceMetadata metadata = new NativeReferenceMetadata();
                metadata.LibraryName = Path.Combine(Path.GetDirectoryName(manifestPath), referenceNode.Attributes ["Name"].Value);

                var attributes = new Dictionary <string, string> ();
                foreach (XmlNode attribute in referenceNode.ChildNodes)
                {
                    attributes [attribute.Name] = attribute.InnerText;
                }

                metadata.ForceLoad                 = ParseAttributeWithDefault(attributes ["ForceLoad"], false);
                metadata.Frameworks                = attributes ["Frameworks"];
                metadata.WeakFrameworks            = attributes ["WeakFrameworks"];
                metadata.LinkerFlags               = attributes ["LinkerFlags"];
                metadata.NeedsGccExceptionHandling = ParseAttributeWithDefault(attributes ["NeedsGccExceptionHandling"], false);
                metadata.IsCxx     = ParseAttributeWithDefault(attributes ["IsCxx"], false);
                metadata.SmartLink = ParseAttributeWithDefault(attributes ["SmartLink"], true);

                // TODO - The project attributes do not contain these bits, is that OK?
                //metadata.LinkTarget = (LinkTarget) Enum.Parse (typeof (LinkTarget), attributes ["LinkTarget"]);
                //metadata.Dlsym = (DlsymOption)Enum.Parse (typeof (DlsymOption), attributes ["Dlsym"]);
                yield return(metadata);
            }
        }
Пример #2
0
        string ExtractNativeLibrary(AssemblyDefinition assembly, NativeReferenceMetadata metadata)
        {
            string path = Path.Combine(App.Cache.Location, metadata.LibraryName);

            if (!Application.IsUptodate(FullPath, path))
            {
                Application.ExtractResource(assembly.MainModule, metadata.LibraryName, path, false);
                Driver.Log(3, "Extracted third-party binding '{0}' from '{1}' to '{2}'", metadata.LibraryName, FullPath, path);
                LogNativeReference(metadata);
            }
            else
            {
                Driver.Log(3, "Target '{0}' is up-to-date.", path);
            }

            if (!File.Exists(path))
            {
                ErrorHelper.Warning(1302, "Could not extract the native library '{0}' from '{1}'. " +
                                    "Please ensure the native library was properly embedded in the managed assembly " +
                                    "(if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').",
                                    metadata.LibraryName, path);
            }

            return(path);
        }
Пример #3
0
 static void LogNativeReference(NativeReferenceMetadata metadata)
 {
     Driver.Log(3, "    LibraryName: {0}", metadata.LibraryName);
     Driver.Log(3, "    From: {0}", metadata.Attribute != null ? "LinkWith" : "Binding Manifest");
     Driver.Log(3, "    ForceLoad: {0}", metadata.ForceLoad);
     Driver.Log(3, "    Frameworks: {0}", metadata.Frameworks);
     Driver.Log(3, "    IsCxx: {0}", metadata.IsCxx);
     Driver.Log(3, "    LinkerFlags: {0}", metadata.LinkerFlags);
     Driver.Log(3, "    LinkTarget: {0}", metadata.LinkTarget);
     Driver.Log(3, "    NeedsGccExceptionHandling: {0}", metadata.NeedsGccExceptionHandling);
     Driver.Log(3, "    SmartLink: {0}", metadata.SmartLink);
     Driver.Log(3, "    WeakFrameworks: {0}", metadata.WeakFrameworks);
 }
Пример #4
0
        void ProcessNativeReferenceOptions(NativeReferenceMetadata metadata)
        {
            // We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled.
            if (!metadata.SmartLink)
            {
                App.DeadStrip = false;
            }

            // Don't add -force_load if the binding's SmartLink value is set and the static registrar is being used.
            if (metadata.ForceLoad && !(metadata.SmartLink && App.Registrar == RegistrarMode.Static))
            {
                ForceLoad = true;
            }

            if (!string.IsNullOrEmpty(metadata.LinkerFlags))
            {
                if (LinkerFlags == null)
                {
                    LinkerFlags = new List <string> ();
                }
                if (!StringUtils.TryParseArguments(metadata.LinkerFlags, out string [] args, out var ex))
Пример #5
0
        string ExtractFramework(AssemblyDefinition assembly, NativeReferenceMetadata metadata)
        {
            string path = Path.Combine(App.Cache.Location, metadata.LibraryName);

            var zipPath = path + ".zip";

            if (!Application.IsUptodate(FullPath, zipPath))
            {
                Application.ExtractResource(assembly.MainModule, metadata.LibraryName, zipPath, false);
                Driver.Log(3, "Extracted third-party framework '{0}' from '{1}' to '{2}'", metadata.LibraryName, FullPath, zipPath);
                LogNativeReference(metadata);
            }
            else
            {
                Driver.Log(3, "Target '{0}' is up-to-date.", path);
            }

            if (!File.Exists(zipPath))
            {
                ErrorHelper.Warning(1302, "Could not extract the native framework '{0}' from '{1}'. " +
                                    "Please ensure the native framework was properly embedded in the managed assembly " +
                                    "(if the assembly was built using a binding project, the native framework must be included in the project, and its Build Action must be 'ObjcBindingNativeFramework').",
                                    metadata.LibraryName, zipPath);
            }
            else
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                if (Driver.RunCommand("/usr/bin/unzip", string.Format("-u -o -d {0} {1}", StringUtils.Quote(path), StringUtils.Quote(zipPath))) != 0)
                {
                    throw ErrorHelper.CreateError(1303, "Could not decompress the native framework '{0}' from '{1}'. Please review the build log for more information from the native 'unzip' command.", metadata.LibraryName, zipPath);
                }
            }

            return(path);
        }
Пример #6
0
        void ProcessLinkWithAttributes(AssemblyDefinition assembly)
        {
            //
            // Tasks:
            // * Remove LinkWith attribute: this is done in the linker.
            // * Remove embedded resources related to LinkWith attribute from assembly: this is done at a later stage,
            //   here we just compile a list of resources to remove.
            // * Extract embedded resources related to LinkWith attribute to a file
            // * Modify the linker flags used to build/link the dylib (if fastdev) or the main binary (if !fastdev)
            //

            for (int i = 0; i < assembly.CustomAttributes.Count; i++)
            {
                CustomAttribute attr = assembly.CustomAttributes [i];

                if (attr.Constructor == null)
                {
                    continue;
                }

                TypeReference type = attr.Constructor.DeclaringType;
                if (!type.IsPlatformType("ObjCRuntime", "LinkWithAttribute"))
                {
                    continue;
                }

                // Let the linker remove it the attribute from the assembly
                HasLinkWithAttributes = true;

                LinkWithAttribute       linkWith = GetLinkWithAttribute(attr);
                NativeReferenceMetadata metadata = new NativeReferenceMetadata(linkWith);

                // If we've already processed this native library, skip it
                if (LinkWith.Any(x => Path.GetFileName(x) == metadata.LibraryName) || Frameworks.Any(x => Path.GetFileName(x) == metadata.LibraryName))
                {
                    continue;
                }

                // Remove the resource from the assembly at a later stage.
                if (!string.IsNullOrEmpty(metadata.LibraryName))
                {
                    AddResourceToBeRemoved(metadata.LibraryName);
                }

                ProcessNativeReferenceOptions(metadata);

                if (!string.IsNullOrEmpty(linkWith.LibraryName))
                {
                    if (linkWith.LibraryName.EndsWith(".framework", StringComparison.OrdinalIgnoreCase))
                    {
                        AssertiOSVersionSupportsUserFrameworks(linkWith.LibraryName);

                        Frameworks.Add(ExtractFramework(assembly, metadata));
                    }
                    else
                    {
                        LinkWith.Add(ExtractNativeLibrary(assembly, metadata));
                    }
                }
            }
        }
Пример #7
0
        void ProcessLinkWithAttributes(AssemblyDefinition assembly)
        {
            //
            // Tasks:
            // * Remove LinkWith attribute: this is done in the linker.
            // * Remove embedded resources related to LinkWith attribute from assembly: this is done at a later stage,
            //   here we just compile a list of resources to remove.
            // * Extract embedded resources related to LinkWith attribute to a file
            // * Modify the linker flags used to build/link the dylib (if fastdev) or the main binary (if !fastdev)
            //

            for (int i = 0; i < assembly.CustomAttributes.Count; i++)
            {
                CustomAttribute attr = assembly.CustomAttributes [i];

                if (attr.Constructor == null)
                {
                    continue;
                }

                TypeReference type = attr.Constructor.DeclaringType;
                if (!type.Is("ObjCRuntime", "LinkWithAttribute"))
                {
                    continue;
                }

                // Let the linker remove it the attribute from the assembly
                HasLinkWithAttributes = true;

                LinkWithAttribute       linkWith = GetLinkWithAttribute(attr);
                NativeReferenceMetadata metadata = new NativeReferenceMetadata(linkWith);

                // If we've already processed this native library, skip it
                if (LinkWith.Any(x => Path.GetFileName(x) == metadata.LibraryName) || Frameworks.Any(x => Path.GetFileName(x) == metadata.LibraryName))
                {
                    continue;
                }

                // Remove the resource from the assembly at a later stage.
                if (!string.IsNullOrEmpty(metadata.LibraryName))
                {
                    AddResourceToBeRemoved(metadata.LibraryName);
                }

                ProcessNativeReferenceOptions(metadata);

                if (!string.IsNullOrEmpty(linkWith.LibraryName))
                {
                    switch (Path.GetExtension(linkWith.LibraryName).ToLowerInvariant())
                    {
                    case ".framework":
                        AssertiOSVersionSupportsUserFrameworks(linkWith.LibraryName);
                        Frameworks.Add(ExtractFramework(assembly, metadata));
                        break;

                    case ".xcframework":
                        // this is resolved, at msbuild time, into a framework
                        // but we must ignore it here (can't be the `default` case)
                        break;

                    default:
                        LinkWith.Add(ExtractNativeLibrary(assembly, metadata));
                        break;
                    }
                }
            }
        }
Пример #8
0
        void ProcessNativeReferenceOptions(NativeReferenceMetadata metadata)
        {
            // We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled.
            if (!metadata.SmartLink)
            {
                App.DeadStrip = false;
            }

            // Don't add -force_load if the binding's SmartLink value is set and the static registrar is being used.
            if (metadata.ForceLoad && !(metadata.SmartLink && App.Registrar == RegistrarMode.Static))
            {
                ForceLoad = true;
            }

            if (!string.IsNullOrEmpty(metadata.LinkerFlags))
            {
                if (LinkerFlags == null)
                {
                    LinkerFlags = new List <string> ();
                }
                LinkerFlags.Add(metadata.LinkerFlags);
            }

            if (!string.IsNullOrEmpty(metadata.Frameworks))
            {
                foreach (var f in metadata.Frameworks.Split(new char [] { ' ' }))
                {
                    if (Frameworks == null)
                    {
                        Frameworks = new HashSet <string> ();
                    }
                    Frameworks.Add(f);
                }
            }

            if (!string.IsNullOrEmpty(metadata.WeakFrameworks))
            {
                foreach (var f in metadata.WeakFrameworks.Split(new char [] { ' ' }))
                {
                    if (WeakFrameworks == null)
                    {
                        WeakFrameworks = new HashSet <string> ();
                    }
                    WeakFrameworks.Add(f);
                }
            }

            if (metadata.NeedsGccExceptionHandling)
            {
                NeedsGccExceptionHandling = true;
            }

            if (metadata.IsCxx)
            {
                EnableCxx = true;
            }

#if MONOTOUCH
            if (metadata.Dlsym != DlsymOption.Default)
            {
                App.SetDlsymOption(FullPath, metadata.Dlsym == DlsymOption.Required);
            }
#endif
        }