/// <summary> /// Initializes a new instance of the <see cref="UnixToolchain"/> class. /// </summary> /// <param name="platform">The platform.</param> /// <param name="architecture">The target architecture.</param> /// <param name="toolchainRoots">The root folder for the toolchains installation. If null, then platform must specify tools paths manually.</param> /// <param name="systemCompiler">The system compiler to use. Null if use toolset root.</param> /// <param name="toolchainSubDir">The custom toolchain folder location in <paramref name="toolchainRoots"/> directory. If nul the architecture name will be used.</param> protected UnixToolchain(UnixPlatform platform, TargetArchitecture architecture, string toolchainRoots = null, string systemCompiler = null, string toolchainSubDir = null) : base(platform, architecture) { ArchitectureName = GetToolchainName(platform.Target, architecture); if (toolchainRoots == null) { return; } // Build paths if (systemCompiler != null) { ToolsetRoot = toolchainRoots; ClangPath = UnixPlatform.Which(systemCompiler); ArPath = UnixPlatform.Which("ar"); LlvmArPath = UnixPlatform.Which("llvm-ar"); RanlibPath = UnixPlatform.Which("ranlib"); StripPath = UnixPlatform.Which("strip"); ObjcopyPath = UnixPlatform.Which("objcopy"); LdPath = UnixPlatform.Which("ld"); } else { var exeExtension = Platform.BuildPlatform.ExecutableFileExtension; ToolsetRoot = toolchainSubDir == null?Path.Combine(toolchainRoots, ArchitectureName) : Path.Combine(toolchainRoots, toolchainSubDir); ClangPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "clang++"))) + exeExtension; if (!File.Exists(ClangPath)) { ClangPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "clang"))) + exeExtension; } if (!File.Exists(ClangPath)) { ClangPath = Path.Combine(ToolsetRoot, "bin/clang++") + exeExtension; } if (!File.Exists(ClangPath)) { ClangPath = Path.Combine(ToolsetRoot, "bin/clang") + exeExtension; } ArPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ar"))) + exeExtension; LlvmArPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}", "llvm-ar"))) + exeExtension; RanlibPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ranlib"))) + exeExtension; StripPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "strip"))) + exeExtension; ObjcopyPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "objcopy"))) + exeExtension; LdPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ld"))) + exeExtension; } // Determinate compiler version ClangVersion = GetClangVersion(ClangPath); // Check version if (ClangVersion.Major < 6) { throw new Exception(string.Format("Unsupported Clang version {0}. Minimum supported is 6.", ClangVersion)); } }
/// <summary> /// Initializes a new instance of the <see cref="UnixToolchain"/> class. /// </summary> /// <param name="platform">The platform.</param> /// <param name="architecture">The target architecture.</param> /// <param name="toolchainRoots">The root folder for the toolchains installation.</param> /// <param name="systemCompiler">The system compiler to use. Null if use toolset root.</param> /// <param name="toolchainSubDir">The custom toolchain folder location in <paramref name="toolchainRoots"/> directory. If nul the architecture name will be sued.</param> protected UnixToolchain(UnixPlatform platform, TargetArchitecture architecture, string toolchainRoots, string systemCompiler, string toolchainSubDir = null) : base(platform, architecture) { ArchitectureName = GetToolchainName(platform.Target, architecture); // Build paths if (systemCompiler != null) { ToolsetRoot = toolchainRoots; ClangPath = UnixPlatform.Which(systemCompiler); ArPath = UnixPlatform.Which("ar"); LlvmArPath = UnixPlatform.Which("llvm-ar"); RanlibPath = UnixPlatform.Which("ranlib"); StripPath = UnixPlatform.Which("strip"); ObjcopyPath = UnixPlatform.Which("objcopy"); LdPath = UnixPlatform.Which("ld"); } else { var exeExtension = Platform.BuildPlatform.ExecutableFileExtension; ToolsetRoot = toolchainSubDir == null?Path.Combine(toolchainRoots, ArchitectureName) : Path.Combine(toolchainRoots, toolchainSubDir); ClangPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "clang++"))) + exeExtension; if (!File.Exists(ClangPath)) { ClangPath = Path.Combine(ToolsetRoot, "bin/clang++") + exeExtension; } ArPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ar"))) + exeExtension; LlvmArPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}", "llvm-ar"))) + exeExtension; RanlibPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ranlib"))) + exeExtension; StripPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "strip"))) + exeExtension; ObjcopyPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "objcopy"))) + exeExtension; LdPath = Path.Combine(Path.Combine(ToolsetRoot, string.Format("bin/{0}-{1}", ArchitectureName, "ld"))) + exeExtension; } // Determinate compiler version if (!File.Exists(ClangPath)) { throw new Exception(string.Format("Missing Clang ({0})", ClangPath)); } using (var process = new Process()) { process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.FileName = ClangPath; process.StartInfo.Arguments = "--version"; process.Start(); process.WaitForExit(); if (process.ExitCode == 0) { // Parse the version string data = process.StandardOutput.ReadLine(); Regex versionPattern = new Regex("version \\d+(\\.\\d+)+"); Match versionMatch = versionPattern.Match(data); if (versionMatch.Value.StartsWith("version ")) { var versionString = versionMatch.Value.Replace("version ", ""); string[] parts = versionString.Split('.'); int major = 0, minor = 0, patch = 0; if (parts.Length >= 1) { major = Convert.ToInt32(parts[0]); } if (parts.Length >= 2) { minor = Convert.ToInt32(parts[1]); } if (parts.Length >= 3) { patch = Convert.ToInt32(parts[2]); } ClangVersion = new Version(major, minor, patch); } } else { throw new Exception(string.Format("Failed to get Clang version ({0})", ClangPath)); } } // Check version if (ClangVersion.Major < 6) { throw new Exception(string.Format("Unsupported Clang version {0}. Minimum supported is 6.", ClangVersion)); } }