#if (UNITY_5 || UNITY_5_3_OR_NEWER) && UNITY_IOS using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.iOS.Xcode; using System.Diagnostics; #if UNITY_2017_2_OR_NEWER using UnityEditor.iOS.Xcode.Extensions; #endif using System; using System.Linq; using System.Collections; using System.IO; using System.Collections.Generic; namespace OpenCVForUnity.Editor { public class OpenCVForUnityIOSBuildPostprocessor : MonoBehaviour { [PostProcessBuild] public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { string opencvFrameworkPath = Directory.GetDirectories(path, "opencv2.framework", SearchOption.AllDirectories).FirstOrDefault(); if (string.IsNullOrEmpty(opencvFrameworkPath)) throw new System.Exception("Can't find opencv2.framework"); string opencvLibraryPath = Directory.GetFiles(path, "libopencvforunity.a", SearchOption.AllDirectories).FirstOrDefault(); if (string.IsNullOrEmpty(opencvLibraryPath)) throw new System.Exception("Can't find libopencvforunity.a"); //Remove the architecture for the simulator. if (PlayerSettings.iOS.sdkVersion == iOSSdkVersion.DeviceSDK) { #if UNITY_EDITOR_OSX RemoveSimulatorArchitectures(Path.GetDirectoryName(opencvFrameworkPath), "opencv2.framework/opencv2"); RemoveSimulatorArchitectures(Path.GetDirectoryName(opencvLibraryPath), "libopencvforunity.a"); #else UnityEngine.Debug.LogError("The RemoveSimulatorArchitectures() method fails when outputting an Xcode project in UnityEditor on non-macOS.\nBefore outputting the Xcode project, please execute the following command on macOS.\n\n//remove i386 architectures.\nlipo - remove i386 opencv2.framework / opencv2 - o opencv2.framework / opencv2\n//remove x86_64 architectures.\nlipo - remove x86_64 opencv2.framework / opencv2 - o opencv2.framework / opencv2\n//check the architectures.\nlipo - info opencv2.framework / opencv2\n\n//remove i386 architectures.\nlipo - remove i386 libopencvforunity.a - o libopencvforunity.a\n//remove x86_64 architectures.\nlipo - remove x86_64 libopencvforunity.a - o libopencvforunity.a\n//check the architectures.\nlipo - info libopencvforunity.a\n"); #endif } //Set opencv2.framework to Embedded Binaries. #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; #else string projPath = PBXProject.GetPBXProjectPath(path); #endif PBXProject proj = new PBXProject(); proj.ReadFromString(System.IO.File.ReadAllText(projPath)); #if UNITY_2019_3_OR_NEWER string target = proj.GetUnityFrameworkTargetGuid(); #elif UNITY_5_0 || UNITY_5_1 || UNITY5_2 string target = proj.TargetGuidByName("Unity-iPhone"); #else string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif #if !UNITY_2018_1_OR_NEWER && UNITY_2017_2_OR_NEWER string fileGuid = proj.FindFileGuidByProjectPath(opencvFrameworkPath.Substring(path.Length + 1)); proj.AddFileToBuild(target, fileGuid); proj.AddFileToEmbedFrameworks(target, fileGuid); foreach (var configName in proj.BuildConfigNames()) { var configGuid = proj.BuildConfigByName(target, configName); proj.SetBuildPropertyForConfig(configGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } #endif #if UNITY_2018_3_0 || UNITY_2018_3_1 || UNITY_2018_3_2 || UNITY_2018_3_3 proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); #endif File.WriteAllText(projPath, proj.WriteToString()); //Check if the Target minimum iOS Version is set to 9.0 or higher. #if UNITY_5_5_OR_NEWER if ((int)Convert.ToDecimal(PlayerSettings.iOS.targetOSVersionString) < 9) { #else if ((int)PlayerSettings.iOS.targetOSVersion < (int)iOSTargetOSVersion.iOS_9_0) { #endif UnityEngine.Debug.LogError("Please set Target minimum iOS Version to 9.0 or higher."); } } } /// /// Removes the simulator architectures. /// /// Working directory. /// File path. private static void RemoveSimulatorArchitectures(string workingDirectory, string filePath) { if (!IsSimulatorArchitectures(workingDirectory, filePath)) return; Process process = new Process(); process.StartInfo.FileName = "/bin/bash"; process.StartInfo.WorkingDirectory = workingDirectory; process.StartInfo.Arguments = "-c \" "; process.StartInfo.Arguments += "lipo -remove i386 " + filePath + " -o " + filePath + ";"; process.StartInfo.Arguments += "lipo -remove x86_64 " + filePath + " -o " + filePath + ";"; process.StartInfo.Arguments += "lipo -info " + filePath + ";"; process.StartInfo.Arguments += " \""; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.Start(); string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); process.Close(); if (string.IsNullOrEmpty(error)) { UnityEngine.Debug.Log("Success RemoveSimulatorArchitectures() : " + output); } else { UnityEngine.Debug.LogError("Error RemoveSimulatorArchitectures() : " + error); } } /// /// Whether the file contains the simulator architectures? /// /// Working directory. /// File path. private static bool IsSimulatorArchitectures(string workingDirectory, string filePath) { Process process = new Process(); process.StartInfo.FileName = "/bin/bash"; process.StartInfo.WorkingDirectory = workingDirectory; process.StartInfo.Arguments = "-c \" "; process.StartInfo.Arguments += "lipo -archs " + filePath + ";"; process.StartInfo.Arguments += " \""; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.Start(); string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); process.Close(); //if (string.IsNullOrEmpty(error)) //{ // UnityEngine.Debug.Log("Success IsSimulatorArchitectures() : " + output); //} //else //{ // UnityEngine.Debug.LogError("Error IsSimulatorArchitectures() : " + error); // return false; //} return output.Contains("i386") || output.Contains("x86_64"); } } } #endif