diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs index a7b059ce0..499f93a7b 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs @@ -42,7 +42,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework BuildTarget target; if (!Targets.TryGetValue(name, out target)) { - Reporter.Verbose.WriteLine($"Skipping undefined target: {name}"); + throw new Exception($"Undefined target: {name}"); } // Check if it's been completed @@ -82,6 +82,11 @@ namespace Microsoft.DotNet.Cli.Build.Framework private BuildTargetResult ExecTarget(BuildTarget target) { + if (target == null) + { + throw new ArgumentNullException("target"); + } + var sectionName = $"{target.Name.PadRight(_maxTargetLen + 2).Yellow()} ({target.Source.White()})"; BuildReporter.BeginSection("TARGET", sectionName); diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs new file mode 100644 index 000000000..0e1cd030d --- /dev/null +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; +using Microsoft.Extensions.PlatformAbstractions; + +public static class CurrentPlatform +{ + public static bool IsWindows + { + get + { + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + } + } + + public static bool IsOSX + { + get + { + return RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + } + } + + public static bool IsLinux + { + get + { + return RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + } + } + + public static bool IsUbuntu + { + get + { + var osname = PlatformServices.Default.Runtime.OperatingSystem; + return string.Equals(osname, "ubuntu", StringComparison.OrdinalIgnoreCase); + } + } + + public static bool IsCentOS + { + get + { + var osname = PlatformServices.Default.Runtime.OperatingSystem; + return string.Equals(osname, "centos", StringComparison.OrdinalIgnoreCase); + } + } +} \ No newline at end of file diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json b/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json index dd887545d..ff3a3dbc6 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json @@ -3,7 +3,8 @@ "dependencies": { "NETStandard.Library": "1.0.0-rc2-23811", - "System.Diagnostics.Process": "4.1.0-rc2-23811" + "System.Diagnostics.Process": "4.1.0-rc2-23811", + "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537" }, "frameworks": { diff --git a/scripts/dotnet-cli-build/PrepareTargets.cs b/scripts/dotnet-cli-build/PrepareTargets.cs index dc4905c9d..ce39e4ba4 100644 --- a/scripts/dotnet-cli-build/PrepareTargets.cs +++ b/scripts/dotnet-cli-build/PrepareTargets.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Runtime.InteropServices; +using System.Text; using static Microsoft.DotNet.Cli.Build.FS; using static Microsoft.DotNet.Cli.Build.Utils; @@ -17,6 +18,9 @@ namespace Microsoft.DotNet.Cli.Build [Target(nameof(Init), nameof(RestorePackages))] public static BuildTargetResult Prepare(BuildTargetContext c) => c.Success(); + [Target(nameof(CheckPrereqCmakePresent), nameof(CheckPrereqDebianPackageBuildComponents), nameof(CheckPrereqCoreclrDependencyPackages))] + public static BuildTargetResult CheckPrereqs(BuildTargetContext c) => c.Success(); + // All major targets will depend on this in order to ensure variables are set up right if they are run independently [Target(nameof(GenerateVersions), nameof(CheckPrereqs), nameof(LocateStage0))] public static BuildTargetResult Init(BuildTargetContext c) @@ -91,38 +95,6 @@ namespace Microsoft.DotNet.Cli.Build return c.Success(); } - [Target] - public static BuildTargetResult CheckPrereqs(BuildTargetContext c) - { - try - { - Command.Create("cmake", "--version") - .CaptureStdOut() - .CaptureStdErr() - .Execute(); - } - catch (Exception ex) - { - string message = $@"Error running cmake: {ex.Message} -cmake is required to build the native host 'corehost'"; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - message += Environment.NewLine + "Download it from https://www.cmake.org"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - message += Environment.NewLine + "Ubuntu: 'sudo apt-get install cmake'"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - message += Environment.NewLine + "OS X w/Homebrew: 'brew install cmake'"; - } - return c.Failed(message); - } - - return c.Success(); - } - [Target] public static BuildTargetResult CheckPackageCache(BuildTargetContext c) { @@ -200,6 +172,162 @@ cmake is required to build the native host 'corehost'"; return c.Success(); } + [Target] + public static BuildTargetResult CheckPrereqDebianPackageBuildComponents(BuildTargetContext c) + { + if (!CurrentPlatform.IsUbuntu) + { + return c.Success(); + } + + var debianPackageBuildDependencies = new string[] + { + "devscripts", + "debhelper", + "build-essential" + }; + + var messageBuilder = new StringBuilder(); + + foreach (var package in debianPackageBuildDependencies) + { + if (!AptPackageIsInstalled(package)) + { + messageBuilder.Append($"Error: Debian package build dependency {package} missing."); + messageBuilder.Append(Environment.NewLine); + messageBuilder.Append($"-> install with apt-get install {package}"); + messageBuilder.Append(Environment.NewLine); + } + } + + if (messageBuilder.Length == 0) + { + return c.Success(); + } + else + { + return c.Failed(messageBuilder.ToString()); + } + } + + [Target] + public static BuildTargetResult CheckPrereqCoreclrDependencyPackages(BuildTargetContext c) + { + if (!CurrentPlatform.IsUbuntu && !CurrentPlatform.IsCentOS) + { + return c.Success(); + } + + var errorMessageBuilder = new StringBuilder(); + var platformPackageCheckAction = default(Func); + var platformCoreclrDependencies = default(string[]); + + if (CurrentPlatform.IsUbuntu) + { + platformCoreclrDependencies = new string[] + { + "unzip", + "curl", + "libicu-dev", + "libunwind8", + "gettext", + "libssl-dev", + "libcurl3-gnutls", + "zlib1g", + "liblttng-ust-dev", + "lldb-3.6-dev", + "lldb-3.6" + }; + + platformPackageCheckAction = AptPackageIsInstalled; + } + else if (CurrentPlatform.IsCentOS) + { + platformCoreclrDependencies = new string[] + { + "unzip", + "libunwind", + "gettext", + "libcurl-devel", + "openssl-devel", + "zlib", + "libicu-devel" + }; + + platformPackageCheckAction = YumPackageIsInstalled; + } + + foreach (var package in platformCoreclrDependencies) + { + if (!platformPackageCheckAction(package)) + { + errorMessageBuilder.Append($"Error: Coreclr package dependency {package} missing."); + errorMessageBuilder.Append(Environment.NewLine); + } + } + + if (errorMessageBuilder.Length == 0) + { + return c.Success(); + } + else + { + return c.Failed(errorMessageBuilder.ToString()); + } + } + + [Target] + public static BuildTargetResult CheckPrereqCmakePresent(BuildTargetContext c) + { + try + { + Command.Create("cmake", "--version") + .CaptureStdOut() + .CaptureStdErr() + .Execute(); + } + catch (Exception ex) + { + string message = $@"Error running cmake: {ex.Message} +cmake is required to build the native host 'corehost'"; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + message += Environment.NewLine + "Download it from https://www.cmake.org"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + message += Environment.NewLine + "Ubuntu: 'sudo apt-get install cmake'"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + message += Environment.NewLine + "OS X w/Homebrew: 'brew install cmake'"; + } + return c.Failed(message); + } + + return c.Success(); + } + + private static bool AptPackageIsInstalled(string packageName) + { + var result = Command.Create("dpkg", "-s", packageName) + .CaptureStdOut() + .CaptureStdErr() + .Execute(); + + return result.ExitCode == 0; + } + + private static bool YumPackageIsInstalled(string packageName) + { + var result = Command.Create("yum", "list", "installed", packageName) + .CaptureStdOut() + .CaptureStdErr() + .Execute(); + + return result.ExitCode == 0; + } + private static IDictionary ReadBranchInfo(BuildTargetContext c, string path) { var lines = File.ReadAllLines(path);