Esempio n. 1
0
 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);
     }
 }
Esempio n. 2
0
        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);
                }
            }
        }