Beispiel #1
0
        /// <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));
            }
        }
Beispiel #2
0
        /// <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));
            }
        }