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