Esempio n. 1
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);
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        // Executed in parallel
        public void ExtractNativeLinkInfo()
        {
            // ignore framework assemblies, they won't have any LinkWith attributes
            if (IsFrameworkAssembly)
            {
                return;
            }

            var assembly = AssemblyDefinition;

            if (!assembly.HasCustomAttributes)
            {
                return;
            }

            var    exceptions = new List <Exception> ();
            string path;

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

                // we know we'll modify this assembly, so load its symbols to keep them in sync
                LoadSymbols();

                // Let the linker remove it the attribute from the assembly

                LinkWithAttribute linkWith    = GetLinkWithAttribute(attr);
                string            libraryName = linkWith.LibraryName;

                // Remove the resource from the assembly at a later stage.
                AddResourceToBeRemoved(libraryName);

                // We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled.
                if (!linkWith.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 (linkWith.ForceLoad && !(linkWith.SmartLink && App.Registrar == RegistrarMode.Static))
                {
                    ForceLoad = true;
                }

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

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

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

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

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

                path = Path.Combine(Cache.Location, libraryName);
                if (path.EndsWith(".framework"))
                {
#if MONOTOUCH
                    if (App.DeploymentTarget.Major < 8)
                    {
                        throw ErrorHelper.CreateError(1305, "The binding library '{0}' contains a user framework ({0}), but embedded user frameworks require iOS 8.0 (the deployment target is {1}). Please set the deployment target in the Info.plist file to at least 8.0.",
                                                      FileName, Path.GetFileName(path), App.DeploymentTarget);
                    }
#endif
                    var zipPath = path + ".zip";
                    if (!Application.IsUptodate(FullPath, zipPath))
                    {
                        Application.ExtractResource(assembly.MainModule, libraryName, zipPath, false);
                        Driver.Log(3, "Extracted third-party framework '{0}' from '{1}' to '{2}'", libraryName, FullPath, zipPath);
                    }
                    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').",
                                            libraryName, zipPath);
                    }
                    else
                    {
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }

                        if (Driver.RunCommand("/usr/bin/unzip", string.Format("-u -o -d {0} {1}", Driver.Quote(path), Driver.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.", libraryName, zipPath);
                        }
                    }

                    if (Frameworks == null)
                    {
                        Frameworks = new HashSet <string> ();
                    }
                    Frameworks.Add(path);
                }
                else
                {
                    if (!Application.IsUptodate(FullPath, path))
                    {
                        Application.ExtractResource(assembly.MainModule, libraryName, path, false);
                        Driver.Log(3, "Extracted third-party binding '{0}' from '{1}' to '{2}'", libraryName, FullPath, path);
                    }
                    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').",
                                            libraryName, path);
                    }

                    if (LinkWith == null)
                    {
                        LinkWith = new List <string> ();
                    }
                    LinkWith.Add(path);
                }
            }

            if (exceptions != null && exceptions.Count > 0)
            {
                throw new AggregateException(exceptions);
            }

            // Make sure there are no duplicates between frameworks and weak frameworks.
            // Keep the weak ones.
            if (Frameworks != null && WeakFrameworks != null)
            {
                Frameworks.ExceptWith(WeakFrameworks);
            }

            if (NeedsGccExceptionHandling)
            {
                if (LinkerFlags == null)
                {
                    LinkerFlags = new List <string> ();
                }
                LinkerFlags.Add("-lgcc_eh");
            }
        }