static List <string> FilterTargetsIfNeeded(List <string> targets, string lib) { using (FileStream stm = new FileStream(lib, FileMode.Open, FileAccess.Read, FileShare.Read)) { List <string> availableTargets = MachOHelpers.TargetsFromDylib(stm); if (availableTargets.Count == 0) { throw new RuntimeException(ReflectorError.kCantHappenBase + 55, $"library {lib} contains no target architectures."); } else { if (targets == null || targets.Count == 0) { targets = availableTargets; } else { List <string> sectionalTargets = MachOHelpers.CommonTargets(targets, availableTargets); if (sectionalTargets.Count == 0) { StringBuilder sbsrc = new StringBuilder(); foreach (var s in targets.Interleave(", ")) { sbsrc.Append(s); } StringBuilder sbdst = new StringBuilder(); foreach (var s in availableTargets.Interleave(", ")) { sbdst.Append(s); } throw new RuntimeException(ReflectorError.kCantHappenBase + 56, $"No specified target ({sbsrc.ToString ()}) was found in the available targets for {lib} ({sbdst.ToString ()})."); } else { targets = sectionalTargets; } } } return(targets); } }
public void CheckForOptionErrors(ErrorHandling errors) { CheckPath(SwiftBinPath, "path to swift binaries", errors); CheckPath(SwiftLibPath, "path to swift libraries", errors); TypeDatabasePaths.ForEach(path => CheckPath(path, "path to type database files", errors)); EnsureFileExists("swiftc", new string [] { SwiftBinPath }, errors); EnsureFileExists("swift", new string [] { SwiftBinPath }, errors); ModulePaths.ForEach(path => CheckPath(path, "module path", errors)); DylibPaths.ForEach(path => CheckPath(path, "library path", errors)); if (ModuleName != null) { string wholeModule = "lib" + ModuleName + ".dylib"; string libDir = DylibPaths.FirstOrDefault(path => File.Exists(Path.Combine(path, wholeModule))); if (libDir == null) { wholeModule = ModuleName; libDir = DylibPaths.FirstOrDefault(path => File.Exists(Path.Combine(path, wholeModule))); } if (libDir == null) { errors.Add(new ReflectorError(new FileNotFoundException($"Couldn't find module {ModuleName}"))); return; } string libFile = Path.Combine(libDir, wholeModule); using (FileStream stm = new FileStream(libFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { try { List <string> targets = MachOHelpers.TargetsFromDylib(stm); Targets = FilterTargetsIfNeeded(targets, libFile); if (Targets.Count > 0) { var targetOS = targets [0].ClangTargetOS(); if (SwiftGluePath != null) { string path = null; if (targetOS.StartsWith("macos", StringComparison.Ordinal)) { path = Path.Combine(SwiftGluePath, "mac/XamGlue.framework"); } else if (targetOS.StartsWith("ios", StringComparison.Ordinal)) { path = Path.Combine(SwiftGluePath, "iphone/XamGlue.framework"); } else if (targetOS.StartsWith("tvos", StringComparison.Ordinal)) { path = Path.Combine(SwiftGluePath, "appletv/XamGlue.framework"); } else if (targetOS.StartsWith("watchos", StringComparison.Ordinal)) { path = Path.Combine(SwiftGluePath, "watch/XamGlue.framework"); } if (path != null) { ModulePaths.Add(path); DylibPaths.Add(path); } } if (targetOS.StartsWith("macos", StringComparison.Ordinal)) { SwiftLibPath = Path.Combine(SwiftLibPath, "macosx"); } else if (targetOS.StartsWith("ios", StringComparison.Ordinal)) { SwiftLibPath = Path.Combine(SwiftLibPath, "iphoneos"); } else if (targetOS.StartsWith("tvos", StringComparison.Ordinal)) { SwiftLibPath = Path.Combine(SwiftLibPath, "appletvos"); } else if (targetOS.StartsWith("watchos", StringComparison.Ordinal)) { SwiftLibPath = Path.Combine(SwiftLibPath, "watchos"); } } // filter the targets here foreach (string target in Targets) { StringBuilder sb = new StringBuilder(); foreach (string s in ModulePaths.Interleave(", ")) { sb.Append(s); } using (ISwiftModuleLocation loc = SwiftModuleFinder.Find(ModulePaths, ModuleName, target)) { if (loc == null) { errors.Add(new ReflectorError(new FileNotFoundException($"Unable to find swift module file for {ModuleName} in target {target}. Searched in {sb.ToString ()}."))); } } using (ISwiftModuleLocation loc = SwiftModuleFinder.Find(ModulePaths, "XamGlue", target)) { if (loc == null) { errors.Add(new ReflectorError(new FileNotFoundException($"Unable to find swift module file for XamGlue in target {target}. Did you forget to refer to it with -M or -C? Searched in {sb.ToString ()}."))); } } } } catch (Exception err) { errors.Add(new RuntimeException(ReflectorError.kCantHappenBase + 63, true, err, $"{libFile}: {err.Message}")); } } } if (String.IsNullOrEmpty(OutputDirectory)) { ArgumentException ex = new ArgumentException("need to specify an output directory with -o"); errors.Add(ex); } else { if (File.Exists(OutputDirectory) && !File.GetAttributes(OutputDirectory).HasFlag(FileAttributes.Directory)) { errors.Add(new ReflectorError(new ArgumentException($"output directory {OutputDirectory} is a file. It needs to be a directory."))); return; } if (!Directory.Exists(OutputDirectory)) { Directory.CreateDirectory(OutputDirectory); } } }