Bring Host build into separate project

This commit is contained in:
Bryan 2016-05-11 17:20:40 -07:00 committed by Eric Erhardt
parent 07b785c183
commit 7bf08c5bd5
76 changed files with 1065 additions and 320 deletions

View file

@ -0,0 +1,488 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
using static Microsoft.DotNet.Cli.Build.FS;
namespace Microsoft.DotNet.Cli.Build
{
public class CompileTargets
{
public static readonly string CoreCLRVersion = "1.0.2-rc2-24027";
public static readonly bool IsWinx86 = CurrentPlatform.IsWindows && CurrentArchitecture.Isx86;
public static readonly string[] BinariesForCoreHost = new[]
{
"csc"
};
public static readonly string[] ProjectsToPublish = new[]
{
"dotnet"
};
public static readonly string[] FilesToClean = new[]
{
"vbc.exe"
};
public static string HostPackagePlatformRid => HostPackageSupportedRids[
(RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows)
? $"win7-{RuntimeEnvironment.RuntimeArchitecture}"
: RuntimeEnvironment.GetRuntimeIdentifier()];
public static readonly Dictionary<string, string> HostPackageSupportedRids = new Dictionary<string, string>()
{
// Key: Current platform RID. Value: The actual publishable (non-dummy) package name produced by the build system for this RID.
{ "win7-x64", "win7-x64" },
{ "win7-x86", "win7-x86" },
{ "osx.10.10-x64", "osx.10.10-x64" },
{ "osx.10.11-x64", "osx.10.10-x64" },
{ "ubuntu.14.04-x64", "ubuntu.14.04-x64" },
{ "centos.7-x64", "rhel.7-x64" },
{ "rhel.7-x64", "rhel.7-x64" },
{ "rhel.7.2-x64", "rhel.7-x64" },
{ "debian.8-x64", "debian.8-x64" }
};
public const string SharedFrameworkName = "Microsoft.NETCore.App";
public static Crossgen CrossgenUtil = new Crossgen(CoreCLRVersion);
private static string DotnetHostBaseName => $"dotnet{Constants.ExeSuffix}";
private static string DotnetHostFxrBaseName => $"{Constants.DynamicLibPrefix}hostfxr{Constants.DynamicLibSuffix}";
private static string HostPolicyBaseName => $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}";
// Updates the stage 2 with recent changes.
[Target(nameof(PrepareTargets.Init), nameof(CompileStage2))]
public static BuildTargetResult UpdateBuild(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(PrepareTargets.Init), nameof(RestoreLockedCoreHost), nameof(CompileStage1), nameof(CompileStage2))]
public static BuildTargetResult Compile(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(PrepareTargets.Init))]
public static BuildTargetResult RestoreLockedCoreHost(BuildTargetContext c)
{
var hostVersion = c.BuildContext.Get<HostVersion>("HostVersion");
var lockedHostFxrVersion = hostVersion.LockedHostFxrVersion;
var currentRid = HostPackagePlatformRid;
string projectJson = $@"{{
""dependencies"": {{
""Microsoft.NETCore.DotNetHostResolver"" : ""{lockedHostFxrVersion}""
}},
""frameworks"": {{
""netcoreapp1.0"": {{}}
}},
""runtimes"": {{
""{currentRid}"": {{}}
}}
}}";
var tempPjDirectory = Path.Combine(Dirs.Intermediate, "lockedHostTemp");
FS.Rmdir(tempPjDirectory);
Directory.CreateDirectory(tempPjDirectory);
var tempPjFile = Path.Combine(tempPjDirectory, "project.json");
File.WriteAllText(tempPjFile, projectJson);
DotNetCli.Stage0.Restore("--verbosity", "verbose", "--infer-runtimes",
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(tempPjDirectory)
.Execute()
.EnsureSuccessful();
// Clean out before publishing locked binaries
FS.Rmdir(Dirs.CorehostLocked);
// Use specific RIDS for non-backward compatible platforms.
(CurrentPlatform.IsWindows
? DotNetCli.Stage0.Publish("--output", Dirs.CorehostLocked, "--no-build")
: DotNetCli.Stage0.Publish("--output", Dirs.CorehostLocked, "--no-build", "-r", currentRid))
.WorkingDirectory(tempPjDirectory)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(PrepareTargets.Init))]
public static BuildTargetResult CompileStage1(BuildTargetContext c)
{
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
if (Directory.Exists(Dirs.Stage1))
{
Utils.DeleteDirectory(Dirs.Stage1);
}
Directory.CreateDirectory(Dirs.Stage1);
CopySharedHost(Dirs.Stage1);
PublishSharedFramework(c, Dirs.Stage1, DotNetCli.Stage0);
var result = CompileCliSdk(c,
dotnet: DotNetCli.Stage0,
outputDir: Dirs.Stage1);
CleanOutputDir(Path.Combine(Dirs.Stage1, "sdk"));
FS.CopyRecursive(Dirs.Stage1, Dirs.Stage1Symbols);
RemovePdbsFromDir(Path.Combine(Dirs.Stage1, "sdk"));
return result;
}
[Target(nameof(PrepareTargets.Init))]
public static BuildTargetResult CompileStage2(BuildTargetContext c)
{
var configuration = c.BuildContext.Get<string>("Configuration");
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
if (Directory.Exists(Dirs.Stage2))
{
Utils.DeleteDirectory(Dirs.Stage2);
}
Directory.CreateDirectory(Dirs.Stage2);
PublishSharedFramework(c, Dirs.Stage2, DotNetCli.Stage1);
CopySharedHost(Dirs.Stage2);
var result = CompileCliSdk(c,
dotnet: DotNetCli.Stage1,
outputDir: Dirs.Stage2);
if (!result.Success)
{
return result;
}
if (CurrentPlatform.IsWindows)
{
// build projects for nuget packages
var packagingOutputDir = Path.Combine(Dirs.Stage2Compilation, "forPackaging");
Mkdirp(packagingOutputDir);
foreach (var project in PackageTargets.ProjectsToPack)
{
// Just build them, we'll pack later
var packBuildResult = DotNetCli.Stage1.Build(
"--build-base-path",
packagingOutputDir,
"--configuration",
configuration,
Path.Combine(c.BuildContext.BuildDirectory, "src", project))
.Execute();
packBuildResult.EnsureSuccessful();
}
}
CleanOutputDir(Path.Combine(Dirs.Stage2, "sdk"));
FS.CopyRecursive(Dirs.Stage2, Dirs.Stage2Symbols);
RemovePdbsFromDir(Path.Combine(Dirs.Stage2, "sdk"));
return c.Success();
}
private static void CleanOutputDir(string directory)
{
foreach (var file in FilesToClean)
{
FS.RmFilesInDirRecursive(directory, file);
}
}
private static void RemovePdbsFromDir(string directory)
{
FS.RmFilesInDirRecursive(directory, "*.pdb");
}
private static void CopySharedHost(string outputDir)
{
File.Copy(
Path.Combine(Dirs.CorehostLocked, DotnetHostBaseName),
Path.Combine(outputDir, DotnetHostBaseName), true);
File.Copy(
Path.Combine(Dirs.CorehostLocked, DotnetHostFxrBaseName),
Path.Combine(outputDir, DotnetHostFxrBaseName), true);
}
public static void PublishSharedFramework(BuildTargetContext c, string outputDir, DotNetCli dotnetCli)
{
string SharedFrameworkTemplateSourceRoot = Path.Combine(Dirs.RepoRoot, "src", "sharedframework", "framework");
string SharedFrameworkNugetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
string sharedFrameworkRid;
if (RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows)
{
sharedFrameworkRid = $"win7-{RuntimeEnvironment.RuntimeArchitecture}";
}
else
{
sharedFrameworkRid = RuntimeEnvironment.GetRuntimeIdentifier();
}
string SharedFrameworkSourceRoot = GenerateSharedFrameworkProject(c, SharedFrameworkTemplateSourceRoot, sharedFrameworkRid);
dotnetCli.Restore(
"--verbosity", "verbose",
"--disable-parallel",
"--infer-runtimes",
"--fallbacksource", Dirs.CorehostLocalPackages)
.WorkingDirectory(SharedFrameworkSourceRoot)
.Execute()
.EnsureSuccessful();
// We publish to a sub folder of the PublishRoot so tools like heat and zip can generate folder structures easier.
string SharedFrameworkNameAndVersionRoot = Path.Combine(outputDir, "shared", SharedFrameworkName, SharedFrameworkNugetVersion);
c.BuildContext["SharedFrameworkPath"] = SharedFrameworkNameAndVersionRoot;
if (Directory.Exists(SharedFrameworkNameAndVersionRoot))
{
Utils.DeleteDirectory(SharedFrameworkNameAndVersionRoot);
}
dotnetCli.Publish(
"--output", SharedFrameworkNameAndVersionRoot,
"-r", sharedFrameworkRid,
SharedFrameworkSourceRoot).Execute().EnsureSuccessful();
// Clean up artifacts that dotnet-publish generates which we don't need
DeleteMainPublishOutput(SharedFrameworkNameAndVersionRoot, "framework");
File.Delete(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.runtimeconfig.json"));
// Rename the .deps file
var destinationDeps = Path.Combine(SharedFrameworkNameAndVersionRoot, $"{SharedFrameworkName}.deps.json");
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps.json"), destinationDeps);
ChangeEntryPointLibraryName(destinationDeps, null);
// Generate RID fallback graph
string runtimeGraphGeneratorRuntime = null;
switch (RuntimeEnvironment.OperatingSystemPlatform)
{
case Platform.Windows:
runtimeGraphGeneratorRuntime = "win";
break;
case Platform.Linux:
runtimeGraphGeneratorRuntime = "linux";
break;
case Platform.Darwin:
runtimeGraphGeneratorRuntime = "osx";
break;
}
if (!string.IsNullOrEmpty(runtimeGraphGeneratorRuntime))
{
var runtimeGraphGeneratorName = "RuntimeGraphGenerator";
var runtimeGraphGeneratorProject = Path.Combine(Dirs.RepoRoot, "tools", runtimeGraphGeneratorName);
var runtimeGraphGeneratorOutput = Path.Combine(Dirs.Output, "tools", runtimeGraphGeneratorName);
dotnetCli.Publish(
"--output", runtimeGraphGeneratorOutput,
runtimeGraphGeneratorProject).Execute().EnsureSuccessful();
var runtimeGraphGeneratorExe = Path.Combine(runtimeGraphGeneratorOutput, $"{runtimeGraphGeneratorName}{Constants.ExeSuffix}");
Cmd(runtimeGraphGeneratorExe, "--project", SharedFrameworkSourceRoot, "--deps", destinationDeps, runtimeGraphGeneratorRuntime)
.Execute()
.EnsureSuccessful();
}
else
{
c.Error($"Could not determine rid graph generation runtime for platform {RuntimeEnvironment.OperatingSystemPlatform}");
}
File.Copy(
Path.Combine(Dirs.CorehostLocked, DotnetHostBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, DotnetHostBaseName), true);
File.Copy(
Path.Combine(Dirs.CorehostLocked, DotnetHostBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, $"corehost{Constants.ExeSuffix}"), true);
File.Copy(
Path.Combine(Dirs.CorehostLocked, DotnetHostFxrBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, DotnetHostFxrBaseName), true);
// Hostpolicy should be the latest and not the locked version as it is supposed to evolve for
// the framework and has a tight coupling with coreclr's API in the framework.
File.Copy(
Path.Combine(Dirs.CorehostLatest, HostPolicyBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, HostPolicyBaseName), true);
if (File.Exists(Path.Combine(SharedFrameworkNameAndVersionRoot, "mscorlib.ni.dll")))
{
// Publish already places the crossgen'd version of mscorlib into the output, so we can
// remove the IL version
File.Delete(Path.Combine(SharedFrameworkNameAndVersionRoot, "mscorlib.dll"));
}
CrossgenUtil.CrossgenDirectory(c, SharedFrameworkNameAndVersionRoot);
// Generate .version file for sharedfx
var version = SharedFrameworkNugetVersion;
var content = $@"{c.BuildContext["CommitHash"]}{Environment.NewLine}{version}{Environment.NewLine}";
File.WriteAllText(Path.Combine(SharedFrameworkNameAndVersionRoot, ".version"), content);
}
/// <summary>
/// Generates the real shared framework project that will get published.
/// </summary>
/// <param name="sharedFrameworkTemplatePath">The "sharedFramework" source template folder.</param>
private static string GenerateSharedFrameworkProject(BuildTargetContext c, string sharedFrameworkTemplatePath, string rid)
{
string sharedFrameworkProjectPath = Path.Combine(Dirs.Intermediate, "sharedFramework", "framework");
Utils.DeleteDirectory(sharedFrameworkProjectPath);
CopyRecursive(sharedFrameworkTemplatePath, sharedFrameworkProjectPath, true);
string templateFile = Path.Combine(sharedFrameworkProjectPath, "project.json.template");
JObject sharedFrameworkProject = JsonUtils.ReadProject(templateFile);
sharedFrameworkProject["dependencies"]["Microsoft.NETCore.App"] = c.BuildContext.Get<BuildVersion>("BuildVersion").NetCoreAppVersion;
((JObject)sharedFrameworkProject["runtimes"]).RemoveAll();
sharedFrameworkProject["runtimes"][rid] = new JObject();
string projectJsonPath = Path.Combine(sharedFrameworkProjectPath, "project.json");
JsonUtils.WriteProject(sharedFrameworkProject, projectJsonPath);
Rm(templateFile);
return sharedFrameworkProjectPath;
}
private static BuildTargetResult CompileCliSdk(BuildTargetContext c, DotNetCli dotnet, string outputDir)
{
var configuration = c.BuildContext.Get<string>("Configuration");
var buildVersion = c.BuildContext.Get<BuildVersion>("BuildVersion");
var srcDir = Path.Combine(c.BuildContext.BuildDirectory, "src");
outputDir = Path.Combine(outputDir, "sdk", buildVersion.NuGetVersion);
FS.CleanBinObj(c, srcDir);
Rmdir(outputDir);
Mkdirp(outputDir);
foreach (var project in ProjectsToPublish)
{
dotnet.Publish(
"--native-subdirectory",
"--output", outputDir,
"--configuration", configuration,
"--version-suffix", buildVersion.CommitCountString,
Path.Combine(srcDir, project))
.Execute()
.EnsureSuccessful();
}
FixModeFlags(outputDir);
string compilersProject = Path.Combine(Dirs.RepoRoot, "src", "compilers");
dotnet.Publish(compilersProject,
"--output",
outputDir,
"--framework",
"netstandard1.5")
.Execute()
.EnsureSuccessful();
var compilersDeps = Path.Combine(outputDir, "compilers.deps.json");
var compilersRuntimeConfig = Path.Combine(outputDir, "compilers.runtimeconfig.json");
File.Copy(Path.Combine(Dirs.CorehostLocked, DotnetHostBaseName), Path.Combine(outputDir, $"corehost{Constants.ExeSuffix}"), overwrite: true);
File.Copy(Path.Combine(Dirs.CorehostLocked, $"{Constants.DynamicLibPrefix}hostfxr{Constants.DynamicLibSuffix}"), Path.Combine(outputDir, $"{Constants.DynamicLibPrefix}hostfxr{Constants.DynamicLibSuffix}"), overwrite: true);
File.Copy(Path.Combine(Dirs.CorehostLatest, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), Path.Combine(outputDir, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), overwrite: true);
var binaryToCorehostifyOutDir = Path.Combine(outputDir, "runtimes", "any", "native");
// Corehostify binaries
foreach (var binaryToCorehostify in BinariesForCoreHost)
{
try
{
// Yes, it is .exe even on Linux. This is the managed exe we're working with
File.Copy(Path.Combine(binaryToCorehostifyOutDir, $"{binaryToCorehostify}.exe"), Path.Combine(outputDir, $"{binaryToCorehostify}.dll"));
File.Delete(Path.Combine(binaryToCorehostifyOutDir, $"{binaryToCorehostify}.exe"));
File.Copy(compilersDeps, Path.Combine(outputDir, binaryToCorehostify + ".deps.json"));
File.Copy(compilersRuntimeConfig, Path.Combine(outputDir, binaryToCorehostify + ".runtimeconfig.json"));
ChangeEntryPointLibraryName(Path.Combine(outputDir, binaryToCorehostify + ".deps.json"), binaryToCorehostify);
}
catch (Exception ex)
{
return c.Failed($"Failed to corehostify '{binaryToCorehostify}': {ex.ToString()}");
}
}
// cleanup compilers project output we don't need
DeleteMainPublishOutput(outputDir, "compilers");
File.Delete(compilersDeps);
File.Delete(compilersRuntimeConfig);
CrossgenUtil.CrossgenDirectory(c, outputDir);
// Generate .version file
var version = buildVersion.NuGetVersion;
var content = $@"{c.BuildContext["CommitHash"]}{Environment.NewLine}{version}{Environment.NewLine}";
File.WriteAllText(Path.Combine(outputDir, ".version"), content);
return c.Success();
}
private static void ChangeEntryPointLibraryName(string depsFile, string newName)
{
JToken deps;
using (var file = File.OpenText(depsFile))
using (JsonTextReader reader = new JsonTextReader(file))
{
deps = JObject.ReadFrom(reader);
}
string version = null;
foreach (JProperty target in deps["targets"])
{
var targetLibrary = target.Value.Children<JProperty>().FirstOrDefault();
if (targetLibrary == null)
{
continue;
}
version = targetLibrary.Name.Substring(targetLibrary.Name.IndexOf('/') + 1);
if (newName == null)
{
targetLibrary.Remove();
}
else
{
targetLibrary.Replace(new JProperty(newName + '/' + version, targetLibrary.Value));
}
}
if (version != null)
{
var library = deps["libraries"].Children<JProperty>().First();
if (newName == null)
{
library.Remove();
}
else
{
library.Replace(new JProperty(newName + '/' + version, library.Value));
}
using (var file = File.CreateText(depsFile))
using (var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented })
{
deps.WriteTo(writer);
}
}
}
private static void DeleteMainPublishOutput(string path, string name)
{
File.Delete(Path.Combine(path, $"{name}{Constants.ExeSuffix}"));
File.Delete(Path.Combine(path, $"{name}.dll"));
File.Delete(Path.Combine(path, $"{name}.pdb"));
}
}
}

View file

@ -0,0 +1,201 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class DebTargets
{
[Target(nameof(GenerateSharedHostDeb),
nameof(GenerateSharedFrameworkDeb),
nameof(GenerateSdkDeb))]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult GenerateDebs(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(InstallSharedFramework))]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult GenerateSdkDeb(BuildTargetContext c)
{
var channel = c.BuildContext.Get<string>("Channel").ToLower();
var packageName = Monikers.GetSdkDebianPackageName(c);
var version = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
var debFile = c.BuildContext.Get<string>("SdkInstallerFile");
var manPagesDir = Path.Combine(Dirs.RepoRoot, "Documentation", "manpages");
var previousVersionURL = $"https://dotnetcli.blob.core.windows.net/dotnet/{channel}/Installers/Latest/dotnet-ubuntu-x64.latest.deb";
var sdkPublishRoot = c.BuildContext.Get<string>("CLISDKRoot");
var sharedFxDebianPackageName = Monikers.GetDebianSharedFrameworkPackageName(c);
var objRoot = Path.Combine(Dirs.Output, "obj", "debian", "sdk");
if (Directory.Exists(objRoot))
{
Directory.Delete(objRoot, true);
}
Directory.CreateDirectory(objRoot);
Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "package", "package-debian.sh"),
"-v", version,
"-i", sdkPublishRoot,
"-o", debFile,
"-p", packageName,
"-b", Monikers.CLISdkBrandName,
"-m", manPagesDir,
"--framework-debian-package-name", sharedFxDebianPackageName,
"--framework-nuget-name", Monikers.SharedFrameworkName,
"--framework-nuget-version", c.BuildContext.Get<string>("SharedFrameworkNugetVersion"),
"--previous-version-url", previousVersionURL,
"--obj-root", objRoot)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult GenerateSharedHostDeb(BuildTargetContext c)
{
var packageName = Monikers.GetDebianSharedHostPackageName(c);
var version = c.BuildContext.Get<HostVersion>("HostVersion").LockedHostVersion;
var inputRoot = c.BuildContext.Get<string>("SharedHostPublishRoot");
var debFile = c.BuildContext.Get<string>("SharedHostInstallerFile");
var objRoot = Path.Combine(Dirs.Output, "obj", "debian", "sharedhost");
var manPagesDir = Path.Combine(Dirs.RepoRoot, "Documentation", "manpages");
if (Directory.Exists(objRoot))
{
Directory.Delete(objRoot, true);
}
Directory.CreateDirectory(objRoot);
Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "package", "package-sharedhost-debian.sh"),
"--input", inputRoot, "--output", debFile, "-b", Monikers.SharedHostBrandName,
"--obj-root", objRoot, "--version", version, "-m", manPagesDir)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(InstallSharedHost))]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult GenerateSharedFrameworkDeb(BuildTargetContext c)
{
var packageName = Monikers.GetDebianSharedFrameworkPackageName(c);
var version = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
var inputRoot = c.BuildContext.Get<string>("SharedFrameworkPublishRoot");
var debFile = c.BuildContext.Get<string>("SharedFrameworkInstallerFile");
var objRoot = Path.Combine(Dirs.Output, "obj", "debian", "sharedframework");
if (Directory.Exists(objRoot))
{
Directory.Delete(objRoot, true);
}
Directory.CreateDirectory(objRoot);
Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "package", "package-sharedframework-debian.sh"),
"--input", inputRoot, "--output", debFile, "--package-name", packageName, "-b", Monikers.SharedFxBrandName,
"--framework-nuget-name", Monikers.SharedFrameworkName,
"--framework-nuget-version", c.BuildContext.Get<string>("SharedFrameworkNugetVersion"),
"--obj-root", objRoot, "--version", version)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(InstallSDK),
nameof(RunE2ETest),
nameof(RemovePackages))]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult TestDebInstaller(BuildTargetContext c)
{
return c.Success();
}
[Target]
public static BuildTargetResult InstallSharedHost(BuildTargetContext c)
{
InstallPackage(c.BuildContext.Get<string>("SharedHostInstallerFile"));
return c.Success();
}
[Target(nameof(InstallSharedHost))]
public static BuildTargetResult InstallSharedFramework(BuildTargetContext c)
{
InstallPackage(c.BuildContext.Get<string>("SharedFrameworkInstallerFile"));
return c.Success();
}
[Target(nameof(InstallSharedFramework))]
public static BuildTargetResult InstallSDK(BuildTargetContext c)
{
InstallPackage(c.BuildContext.Get<string>("SdkInstallerFile"));
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult RunE2ETest(BuildTargetContext c)
{
Directory.SetCurrentDirectory(Path.Combine(Dirs.RepoRoot, "test", "EndToEnd"));
Cmd("dotnet", "build")
.Execute()
.EnsureSuccessful();
var testResultsPath = Path.Combine(Dirs.Output, "obj", "debian", "test", "debian-endtoend-testResults.xml");
Cmd("dotnet", "test", "-xml", testResultsPath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult RemovePackages(BuildTargetContext c)
{
IEnumerable<string> orderedPackageNames = new List<string>()
{
Monikers.GetSdkDebianPackageName(c),
Monikers.GetDebianSharedFrameworkPackageName(c),
Monikers.GetDebianSharedHostPackageName(c)
};
foreach(var packageName in orderedPackageNames)
{
RemovePackage(packageName);
}
return c.Success();
}
private static void InstallPackage(string packagePath)
{
Cmd("sudo", "dpkg", "-i", packagePath)
.Execute()
.EnsureSuccessful();
}
private static void RemovePackage(string packageName)
{
Cmd("sudo", "dpkg", "-r", packageName)
.Execute()
.EnsureSuccessful();
}
}
}

View file

@ -0,0 +1,23 @@
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public class InstallerTargets
{
[Target(nameof(MsiTargets.GenerateMsis),
nameof(MsiTargets.GenerateBundles),
nameof(PkgTargets.GeneratePkgs),
nameof(DebTargets.GenerateDebs))]
public static BuildTargetResult GenerateInstaller(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(DebTargets.TestDebInstaller))]
public static BuildTargetResult TestInstaller(BuildTargetContext c)
{
return c.Success();
}
}
}

View file

@ -0,0 +1,262 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class MsiTargets
{
private const string ENGINE = "engine.exe";
private const string WixVersion = "3.10.2";
private static string WixRoot
{
get
{
return Path.Combine(Dirs.Output, $"WixTools.{WixVersion}");
}
}
private static string SdkMsi { get; set; }
private static string SdkBundle { get; set; }
private static string SharedHostMsi { get; set; }
private static string SharedFrameworkMsi { get; set; }
private static string SharedFrameworkBundle { get; set; }
private static string SdkEngine { get; set; }
private static string SharedFrameworkEngine { get; set; }
private static string MsiVersion { get; set; }
private static string CliDisplayVersion { get; set; }
private static string CliNugetVersion { get; set; }
private static string Arch { get; } = CurrentArchitecture.Current.ToString();
private static void AcquireWix(BuildTargetContext c)
{
if (File.Exists(Path.Combine(WixRoot, "candle.exe")))
{
return;
}
Directory.CreateDirectory(WixRoot);
c.Info("Downloading WixTools..");
DownloadFile($"https://dotnetcli.blob.core.windows.net/build/wix/wix.{WixVersion}.zip", Path.Combine(WixRoot, "WixTools.zip"));
c.Info("Extracting WixTools..");
ZipFile.ExtractToDirectory(Path.Combine(WixRoot, "WixTools.zip"), WixRoot);
}
private static void DownloadFile(string uri, string destinationPath)
{
using (var httpClient = new HttpClient())
{
var getTask = httpClient.GetStreamAsync(uri);
using (var outStream = File.OpenWrite(destinationPath))
{
getTask.Result.CopyTo(outStream);
}
}
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult InitMsi(BuildTargetContext c)
{
SdkBundle = c.BuildContext.Get<string>("CombinedFrameworkSDKHostInstallerFile");
SdkMsi = Path.ChangeExtension(SdkBundle, "msi");
SdkEngine = GetEngineName(SdkBundle);
SharedFrameworkBundle = c.BuildContext.Get<string>("CombinedFrameworkHostInstallerFile");
SharedHostMsi = Path.ChangeExtension(c.BuildContext.Get<string>("SharedHostInstallerFile"), "msi");
SharedFrameworkMsi = Path.ChangeExtension(c.BuildContext.Get<string>("SharedFrameworkInstallerFile"), "msi");
SharedFrameworkEngine = GetEngineName(SharedFrameworkBundle);
var buildVersion = c.BuildContext.Get<BuildVersion>("BuildVersion");
MsiVersion = buildVersion.GenerateMsiVersion();
CliDisplayVersion = buildVersion.SimpleVersion;
CliNugetVersion = buildVersion.NuGetVersion;
AcquireWix(c);
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi),
nameof(GenerateDotnetSharedHostMsi),
nameof(GenerateDotnetSharedFrameworkMsi),
nameof(GenerateCliSdkMsi))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateMsis(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi),
nameof(GenerateCliSdkBundle),
nameof(GenerateSharedFxBundle))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateBundles(BuildTargetContext c)
{
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateCliSdkMsi(BuildTargetContext c)
{
var cliSdkRoot = c.BuildContext.Get<string>("CLISDKRoot");
var upgradeCode = Utils.GenerateGuidFromName(SdkMsi).ToString().ToUpper();
var cliSdkBrandName = $"'{Monikers.CLISdkBrandName}'";
Cmd("powershell", "-NoProfile", "-NoLogo",
Path.Combine(Dirs.RepoRoot, "packaging", "windows", "clisdk", "generatemsi.ps1"),
cliSdkRoot, SdkMsi, WixRoot, cliSdkBrandName, MsiVersion, CliDisplayVersion, CliNugetVersion, upgradeCode, Arch)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateDotnetSharedHostMsi(BuildTargetContext c)
{
var hostVersion = c.BuildContext.Get<HostVersion>("HostVersion");
var hostMsiVersion = hostVersion.GenerateMsiVersion();
var hostNugetVersion = hostVersion.LockedHostVersion;
var inputDir = c.BuildContext.Get<string>("SharedHostPublishRoot");
var wixObjRoot = Path.Combine(Dirs.Output, "obj", "wix", "sharedhost");
var sharedHostBrandName = $"'{Monikers.SharedHostBrandName}'";
if (Directory.Exists(wixObjRoot))
{
Utils.DeleteDirectory(wixObjRoot);
}
Directory.CreateDirectory(wixObjRoot);
Cmd("powershell", "-NoProfile", "-NoLogo",
Path.Combine(Dirs.RepoRoot, "packaging", "windows", "host", "generatemsi.ps1"),
inputDir, SharedHostMsi, WixRoot, sharedHostBrandName, hostMsiVersion, hostNugetVersion, Arch, wixObjRoot)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateDotnetSharedFrameworkMsi(BuildTargetContext c)
{
var inputDir = c.BuildContext.Get<string>("SharedFrameworkPublishRoot");
var sharedFrameworkNuGetName = Monikers.SharedFrameworkName;
var sharedFrameworkNuGetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
var msiVerison = sharedFrameworkNuGetVersion.Split('-')[0];
var upgradeCode = Utils.GenerateGuidFromName(SharedFrameworkMsi).ToString().ToUpper();
var wixObjRoot = Path.Combine(Dirs.Output, "obj", "wix", "sharedframework");
var sharedFxBrandName = $"'{Monikers.SharedFxBrandName}'";
if (Directory.Exists(wixObjRoot))
{
Utils.DeleteDirectory(wixObjRoot);
}
Directory.CreateDirectory(wixObjRoot);
Cmd("powershell", "-NoProfile", "-NoLogo",
Path.Combine(Dirs.RepoRoot, "packaging", "windows", "sharedframework", "generatemsi.ps1"),
inputDir, SharedFrameworkMsi, WixRoot, sharedFxBrandName, msiVerison, sharedFrameworkNuGetName, sharedFrameworkNuGetVersion, upgradeCode, Arch, wixObjRoot)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateCliSdkBundle(BuildTargetContext c)
{
var upgradeCode = Utils.GenerateGuidFromName(SdkBundle).ToString().ToUpper();
var cliSdkBrandName = $"'{Monikers.CLISdkBrandName}'";
Cmd("powershell", "-NoProfile", "-NoLogo",
Path.Combine(Dirs.RepoRoot, "packaging", "windows", "clisdk", "generatebundle.ps1"),
SdkMsi, SharedFrameworkMsi, SharedHostMsi, SdkBundle, WixRoot, cliSdkBrandName, MsiVersion, CliDisplayVersion, CliNugetVersion, upgradeCode, Arch)
.EnvironmentVariable("Stage2Dir", Dirs.Stage2)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateSharedFxBundle(BuildTargetContext c)
{
var sharedFrameworkNuGetName = Monikers.SharedFrameworkName;
var sharedFrameworkNuGetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
var upgradeCode = Utils.GenerateGuidFromName(SharedFrameworkBundle).ToString().ToUpper();
var sharedFxBrandName = $"'{Monikers.SharedFxBrandName}'";
Cmd("powershell", "-NoProfile", "-NoLogo",
Path.Combine(Dirs.RepoRoot, "packaging", "windows", "sharedframework", "generatebundle.ps1"),
SharedFrameworkMsi, SharedHostMsi, SharedFrameworkBundle, WixRoot, sharedFxBrandName, MsiVersion, CliDisplayVersion, sharedFrameworkNuGetName, sharedFrameworkNuGetVersion, upgradeCode, Arch)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult ExtractEngineFromBundle(BuildTargetContext c)
{
ExtractEngineFromBundleHelper(SdkBundle, SdkEngine);
ExtractEngineFromBundleHelper(SharedFrameworkBundle, SharedFrameworkEngine);
return c.Success();
}
[Target(nameof(MsiTargets.InitMsi))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult ReattachEngineToBundle(BuildTargetContext c)
{
ReattachEngineToBundleHelper(SdkBundle, SdkEngine);
ReattachEngineToBundleHelper(SharedFrameworkBundle, SharedFrameworkEngine);
return c.Success();
}
private static string GetEngineName(string bundle)
{
var engine = $"{Path.GetFileNameWithoutExtension(bundle)}-{ENGINE}";
return Path.Combine(Path.GetDirectoryName(bundle), engine);
}
private static void ExtractEngineFromBundleHelper(string bundle, string engine)
{
Cmd($"{WixRoot}\\insignia.exe", "-ib", bundle, "-o", engine)
.Execute()
.EnsureSuccessful();
}
private static void ReattachEngineToBundleHelper(string bundle, string engine)
{
Cmd($"{WixRoot}\\insignia.exe", "-ab", engine, bundle, "-o", bundle)
.Execute()
.EnsureSuccessful();
File.Delete(engine);
}
}
}

View file

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Cli.Build
{
public class PackageDependencies
{
internal static string[] DebianPackageBuildDependencies
{
get
{
return new string[]
{
"devscripts",
"debhelper",
"build-essential"
};
}
}
internal static string[] UbuntuCoreclrAndCoreFxDependencies
{
get
{
return new string[]
{
"libc6",
"libedit2",
"libffi6",
"libgcc1",
"libicu52",
"liblldb-3.6",
"libllvm3.6",
"liblttng-ust0",
"liblzma5",
"libncurses5",
"libpython2.7",
"libstdc++6",
"libtinfo5",
"libunwind8",
"liburcu1",
"libuuid1",
"zlib1g",
"libasn1-8-heimdal",
"libcomerr2",
"libcurl3",
"libgcrypt11",
"libgnutls26",
"libgpg-error0",
"libgssapi3-heimdal",
"libgssapi-krb5-2",
"libhcrypto4-heimdal",
"libheimbase1-heimdal",
"libheimntlm0-heimdal",
"libhx509-5-heimdal",
"libidn11",
"libk5crypto3",
"libkeyutils1",
"libkrb5-26-heimdal",
"libkrb5-3",
"libkrb5support0",
"libldap-2.4-2",
"libp11-kit0",
"libroken18-heimdal",
"librtmp0",
"libsasl2-2",
"libsqlite3-0",
"libssl1.0.0",
"libtasn1-6",
"libwind0-heimdal"
};
}
}
internal static string[] CentosCoreclrAndCoreFxDependencies
{
get
{
return new string[]
{
"unzip",
"libunwind",
"gettext",
"libcurl-devel",
"openssl-devel",
"zlib",
"libicu-devel"
};
}
}
}
}

View file

@ -0,0 +1,328 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public static class PackageTargets
{
public static readonly string[] ProjectsToPack = new string[]
{
"dotnet-compile-fsc",
"Microsoft.DotNet.Cli.Utils",
"Microsoft.DotNet.Compiler.Common",
"Microsoft.DotNet.Files",
"Microsoft.DotNet.InternalAbstractions",
"Microsoft.DotNet.ProjectModel",
"Microsoft.DotNet.ProjectModel.Loader",
"Microsoft.DotNet.ProjectModel.Workspaces",
"Microsoft.Extensions.DependencyModel",
"Microsoft.Extensions.Testing.Abstractions"
};
[Target(nameof(PackageTargets.CopyCLISDKLayout),
nameof(PackageTargets.CopySharedHostLayout),
nameof(PackageTargets.CopySharedFxLayout),
nameof(PackageTargets.CopyCombinedFrameworkSDKHostLayout),
nameof(PackageTargets.CopyCombinedFrameworkHostLayout),
nameof(PackageTargets.CopyCombinedFrameworkSDKLayout))]
public static BuildTargetResult InitPackage(BuildTargetContext c)
{
Directory.CreateDirectory(Dirs.Packages);
return c.Success();
}
[Target(nameof(PrepareTargets.Init),
nameof(PackageTargets.InitPackage),
nameof(PackageTargets.GenerateVersionBadge),
nameof(PackageTargets.GenerateCompressedFile),
nameof(InstallerTargets.GenerateInstaller),
nameof(PackageTargets.GenerateNugetPackages),
nameof(InstallerTargets.TestInstaller))]
[Environment("DOTNET_BUILD_SKIP_PACKAGING", null, "0", "false")]
public static BuildTargetResult Package(BuildTargetContext c)
{
return c.Success();
}
[Target]
public static BuildTargetResult GenerateVersionBadge(BuildTargetContext c)
{
var buildVersion = c.BuildContext.Get<BuildVersion>("BuildVersion");
var versionSvg = Path.Combine(Dirs.RepoRoot, "resources", "images", "version_badge.svg");
var outputVersionSvg = c.BuildContext.Get<string>("VersionBadge");
var versionSvgContent = File.ReadAllText(versionSvg);
versionSvgContent = versionSvgContent.Replace("ver_number", buildVersion.NuGetVersion);
File.WriteAllText(outputVersionSvg, versionSvgContent);
return c.Success();
}
[Target]
public static BuildTargetResult CopyCLISDKLayout(BuildTargetContext c)
{
var cliSdkRoot = Path.Combine(Dirs.Output, "obj", "clisdk");
if (Directory.Exists(cliSdkRoot))
{
Utils.DeleteDirectory(cliSdkRoot);
}
Directory.CreateDirectory(cliSdkRoot);
Utils.CopyDirectoryRecursively(Path.Combine(Dirs.Stage2, "sdk"), cliSdkRoot, true);
FixPermissions(cliSdkRoot);
c.BuildContext["CLISDKRoot"] = cliSdkRoot;
return c.Success();
}
[Target]
public static BuildTargetResult CopySharedHostLayout(BuildTargetContext c)
{
var sharedHostRoot = Path.Combine(Dirs.Output, "obj", "sharedHost");
if (Directory.Exists(sharedHostRoot))
{
Utils.DeleteDirectory(sharedHostRoot);
}
Directory.CreateDirectory(sharedHostRoot);
foreach (var file in Directory.GetFiles(Dirs.Stage2, "*", SearchOption.TopDirectoryOnly))
{
var destFile = file.Replace(Dirs.Stage2, sharedHostRoot);
File.Copy(file, destFile, true);
}
FixPermissions(sharedHostRoot);
c.BuildContext["SharedHostPublishRoot"] = sharedHostRoot;
return c.Success();
}
[Target]
public static BuildTargetResult CopySharedFxLayout(BuildTargetContext c)
{
var sharedFxRoot = Path.Combine(Dirs.Output, "obj", "sharedFx");
if (Directory.Exists(sharedFxRoot))
{
Utils.DeleteDirectory(sharedFxRoot);
}
Directory.CreateDirectory(sharedFxRoot);
Utils.CopyDirectoryRecursively(Path.Combine(Dirs.Stage2, "shared"), sharedFxRoot, true);
FixPermissions(sharedFxRoot);
c.BuildContext["SharedFrameworkPublishRoot"] = sharedFxRoot;
return c.Success();
}
[Target]
public static BuildTargetResult CopyCombinedFrameworkSDKHostLayout(BuildTargetContext c)
{
var combinedRoot = Path.Combine(Dirs.Output, "obj", "combined-framework-sdk-host");
if (Directory.Exists(combinedRoot))
{
Utils.DeleteDirectory(combinedRoot);
}
string sdkPublishRoot = c.BuildContext.Get<string>("CLISDKRoot");
Utils.CopyDirectoryRecursively(sdkPublishRoot, combinedRoot);
string sharedFrameworkPublishRoot = c.BuildContext.Get<string>("SharedFrameworkPublishRoot");
Utils.CopyDirectoryRecursively(sharedFrameworkPublishRoot, combinedRoot);
string sharedHostPublishRoot = c.BuildContext.Get<string>("SharedHostPublishRoot");
Utils.CopyDirectoryRecursively(sharedHostPublishRoot, combinedRoot);
c.BuildContext["CombinedFrameworkSDKHostRoot"] = combinedRoot;
return c.Success();
}
[Target]
public static BuildTargetResult CopyCombinedFrameworkHostLayout(BuildTargetContext c)
{
var combinedRoot = Path.Combine(Dirs.Output, "obj", "combined-framework-host");
if (Directory.Exists(combinedRoot))
{
Utils.DeleteDirectory(combinedRoot);
}
string sharedFrameworkPublishRoot = c.BuildContext.Get<string>("SharedFrameworkPublishRoot");
Utils.CopyDirectoryRecursively(sharedFrameworkPublishRoot, combinedRoot);
string sharedHostPublishRoot = c.BuildContext.Get<string>("SharedHostPublishRoot");
Utils.CopyDirectoryRecursively(sharedHostPublishRoot, combinedRoot);
c.BuildContext["CombinedFrameworkHostRoot"] = combinedRoot;
return c.Success();
}
[Target]
public static BuildTargetResult CopyCombinedFrameworkSDKLayout(BuildTargetContext c)
{
var combinedRoot = Path.Combine(Dirs.Output, "obj", "combined-framework-sdk");
if (Directory.Exists(combinedRoot))
{
Utils.DeleteDirectory(combinedRoot);
}
string sdkPublishRoot = c.BuildContext.Get<string>("CLISDKRoot");
Utils.CopyDirectoryRecursively(sdkPublishRoot, combinedRoot);
string sharedFrameworkPublishRoot = c.BuildContext.Get<string>("SharedFrameworkPublishRoot");
Utils.CopyDirectoryRecursively(sharedFrameworkPublishRoot, combinedRoot);
c.BuildContext["CombinedFrameworkSDKRoot"] = combinedRoot;
return c.Success();
}
[Target(nameof(PackageTargets.GenerateZip), nameof(PackageTargets.GenerateTarBall))]
public static BuildTargetResult GenerateCompressedFile(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(PackageTargets.InitPackage))]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult GenerateZip(BuildTargetContext c)
{
CreateZipFromDirectory(c.BuildContext.Get<string>("CombinedFrameworkSDKHostRoot"), c.BuildContext.Get<string>("CombinedFrameworkSDKHostCompressedFile"));
CreateZipFromDirectory(c.BuildContext.Get<string>("CombinedFrameworkHostRoot"), c.BuildContext.Get<string>("CombinedFrameworkHostCompressedFile"));
CreateZipFromDirectory(c.BuildContext.Get<string>("CombinedFrameworkSDKRoot"), c.BuildContext.Get<string>("CombinedFrameworkSDKCompressedFile"));
CreateZipFromDirectory(Path.Combine(Dirs.Stage2Symbols, "sdk"), c.BuildContext.Get<string>("SdkSymbolsCompressedFile"));
return c.Success();
}
[Target(nameof(PackageTargets.InitPackage))]
[BuildPlatforms(BuildPlatform.Unix)]
public static BuildTargetResult GenerateTarBall(BuildTargetContext c)
{
CreateTarBallFromDirectory(c.BuildContext.Get<string>("CombinedFrameworkSDKHostRoot"), c.BuildContext.Get<string>("CombinedFrameworkSDKHostCompressedFile"));
CreateTarBallFromDirectory(c.BuildContext.Get<string>("CombinedFrameworkHostRoot"), c.BuildContext.Get<string>("CombinedFrameworkHostCompressedFile"));
CreateTarBallFromDirectory(Path.Combine(Dirs.Stage2Symbols, "sdk"), c.BuildContext.Get<string>("SdkSymbolsCompressedFile"));
return c.Success();
}
[Target]
public static BuildTargetResult GenerateNugetPackages(BuildTargetContext c)
{
var versionSuffix = c.BuildContext.Get<BuildVersion>("BuildVersion").CommitCountString;
var configuration = c.BuildContext.Get<string>("Configuration");
var env = GetCommonEnvVars(c);
var dotnet = DotNetCli.Stage2;
var packagingBuildBasePath = Path.Combine(Dirs.Stage2Compilation, "forPackaging");
FS.Mkdirp(Dirs.PackagesIntermediate);
FS.Mkdirp(Dirs.Packages);
foreach (var projectName in ProjectsToPack)
{
var projectFile = Path.Combine(Dirs.RepoRoot, "src", projectName, "project.json");
dotnet.Pack(
projectFile,
"--no-build",
"--build-base-path", packagingBuildBasePath,
"--output", Dirs.PackagesIntermediate,
"--configuration", configuration,
"--version-suffix", versionSuffix)
.Execute()
.EnsureSuccessful();
}
var packageFiles = Directory.EnumerateFiles(Dirs.PackagesIntermediate, "*.nupkg");
foreach (var packageFile in packageFiles)
{
if (!packageFile.EndsWith(".symbols.nupkg"))
{
var destinationPath = Path.Combine(Dirs.Packages, Path.GetFileName(packageFile));
File.Copy(packageFile, destinationPath, overwrite: true);
}
}
return c.Success();
}
internal static Dictionary<string, string> GetCommonEnvVars(BuildTargetContext c)
{
// Set up the environment variables previously defined by common.sh/ps1
// This is overkill, but I want to cover all the variables used in all OSes (including where some have the same names)
var buildVersion = c.BuildContext.Get<BuildVersion>("BuildVersion");
var configuration = c.BuildContext.Get<string>("Configuration");
var architecture = RuntimeEnvironment.RuntimeArchitecture;
var env = new Dictionary<string, string>()
{
{ "RID", RuntimeEnvironment.GetRuntimeIdentifier() },
{ "OSNAME", RuntimeEnvironment.OperatingSystem },
{ "TFM", "dnxcore50" },
{ "REPOROOT", Dirs.RepoRoot },
{ "OutputDir", Dirs.Output },
{ "Stage1Dir", Dirs.Stage1 },
{ "Stage1CompilationDir", Dirs.Stage1Compilation },
{ "Stage2Dir", Dirs.Stage2 },
{ "STAGE2_DIR", Dirs.Stage2 },
{ "Stage2CompilationDir", Dirs.Stage2Compilation },
{ "PackageDir", Path.Combine(Dirs.Packages) }, // Legacy name
{ "TestBinRoot", Dirs.TestOutput },
{ "TestPackageDir", Dirs.TestPackages },
{ "MajorVersion", buildVersion.Major.ToString() },
{ "MinorVersion", buildVersion.Minor.ToString() },
{ "PatchVersion", buildVersion.Patch.ToString() },
{ "CommitCountVersion", buildVersion.CommitCountString },
{ "COMMIT_COUNT_VERSION", buildVersion.CommitCountString },
{ "DOTNET_CLI_VERSION", buildVersion.SimpleVersion },
{ "DOTNET_MSI_VERSION", buildVersion.GenerateMsiVersion() },
{ "VersionSuffix", buildVersion.VersionSuffix },
{ "CONFIGURATION", configuration },
{ "ARCHITECTURE", architecture }
};
return env;
}
private static void CreateZipFromDirectory(string directory, string artifactPath)
{
if (File.Exists(artifactPath))
{
File.Delete(artifactPath);
}
ZipFile.CreateFromDirectory(directory, artifactPath, CompressionLevel.Optimal, false);
}
private static void CreateTarBallFromDirectory(string directory, string artifactPath)
{
if (File.Exists(artifactPath))
{
File.Delete(artifactPath);
}
Cmd("tar", "-czf", artifactPath, "-C", directory, ".")
.Execute()
.EnsureSuccessful();
}
private static void FixPermissions(string directory)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Reset everything to user readable/writeable and group and world readable.
FS.ChmodAll(directory, "*", "644");
// Now make things that should be executable, executable.
FS.FixModeFlags(directory);
}
}
}
}

View file

@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class PkgTargets
{
public static string PkgsIntermediateDir { get; set; }
public static string SharedHostComponentId { get; set; }
public static string SharedFxComponentId { get; set; }
public static string SharedFxPkgId { get; set; }
public static string SharedFrameworkNugetVersion { get; set; }
public static string CLISdkComponentId { get; set; }
public static string CLISdkPkgId { get; set; }
public static string CLISdkNugetVersion { get; set; }
[Target]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult InitPkg(BuildTargetContext c)
{
PkgsIntermediateDir = Path.Combine(Dirs.Packages, "intermediate");
Directory.CreateDirectory(PkgsIntermediateDir);
SharedHostComponentId = $"com.microsoft.dotnet.sharedhost.component.osx.x64";
string sharedFrameworkNugetName = Monikers.SharedFrameworkName;
SharedFrameworkNugetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
SharedFxComponentId = $"com.microsoft.dotnet.sharedframework.{sharedFrameworkNugetName}.{SharedFrameworkNugetVersion}.component.osx.x64";
SharedFxPkgId = $"com.microsoft.dotnet.{sharedFrameworkNugetName}.{SharedFrameworkNugetVersion}.osx.x64";
CLISdkNugetVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
CLISdkComponentId = $"com.microsoft.dotnet.dev.{CLISdkNugetVersion}.component.osx.x64";
CLISdkPkgId = $"com.microsoft.dotnet.dev.{CLISdkNugetVersion}.osx.x64";
return c.Success();
}
[Target(nameof(InitPkg), nameof(GenerateSharedFrameworkProductArchive), nameof(GenerateCLISdkProductArchive))]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GeneratePkgs(BuildTargetContext c)
{
return c.Success();
}
[Target(nameof(GenerateCLISdkPkg))]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GenerateCLISdkProductArchive(BuildTargetContext c)
{
string resourcePath = Path.Combine(Dirs.RepoRoot, "packaging", "osx", "clisdk", "resources");
string outFilePath = Path.Combine(Dirs.Packages, c.BuildContext.Get<string>("CombinedFrameworkSDKHostInstallerFile"));
string inputDistTemplatePath = Path.Combine(
Dirs.RepoRoot,
"packaging",
"osx",
"clisdk",
"Distribution-Template");
string distTemplate = File.ReadAllText(inputDistTemplatePath);
string distributionPath = Path.Combine(PkgsIntermediateDir, "CLI-SDK-Formatted-Distribution-Template.xml");
string formattedDistContents =
distTemplate.Replace("{SharedFxComponentId}", SharedFxComponentId)
.Replace("{SharedHostComponentId}", SharedHostComponentId)
.Replace("{CLISdkComponentId}", CLISdkComponentId)
.Replace("{CLISdkNugetVersion}", CLISdkNugetVersion)
.Replace("{CLISdkBrandName}", Monikers.CLISdkBrandName)
.Replace("{SharedFxBrandName}", Monikers.SharedFxBrandName)
.Replace("{SharedHostBrandName}", Monikers.SharedHostBrandName);
File.WriteAllText(distributionPath, formattedDistContents);
Cmd("productbuild",
"--version", CLISdkNugetVersion,
"--identifier", CLISdkPkgId,
"--package-path", PkgsIntermediateDir,
"--resources", resourcePath,
"--distribution", distributionPath,
outFilePath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GenerateCLISdkPkg(BuildTargetContext c)
{
string outFilePath = Path.Combine(PkgsIntermediateDir, CLISdkComponentId + ".pkg");
string installLocation = "/usr/local/share/dotnet";
string scriptsLocation = Path.Combine(Dirs.RepoRoot, "packaging", "osx", "clisdk", "scripts");
Cmd("pkgbuild",
"--root", c.BuildContext.Get<string>("CLISDKRoot"),
"--identifier", CLISdkComponentId,
"--version", CLISdkNugetVersion,
"--install-location", installLocation,
"--scripts", scriptsLocation,
outFilePath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target(nameof(GenerateSharedFrameworkPkg), nameof(GenerateSharedHostPkg))]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GenerateSharedFrameworkProductArchive(BuildTargetContext c)
{
string resourcePath = Path.Combine(Dirs.RepoRoot, "packaging", "osx", "sharedframework", "resources");
string outFilePath = Path.Combine(PkgsIntermediateDir, c.BuildContext.Get<string>("CombinedFrameworkHostInstallerFile"));
string inputDistTemplatePath = Path.Combine(
Dirs.RepoRoot,
"packaging",
"osx",
"sharedframework",
"shared-framework-distribution-template.xml");
string distTemplate = File.ReadAllText(inputDistTemplatePath);
string distributionPath = Path.Combine(PkgsIntermediateDir, "shared-framework-formatted-distribution.xml");
string formattedDistContents =
distTemplate.Replace("{SharedFxComponentId}", SharedFxComponentId)
.Replace("{SharedHostComponentId}", SharedHostComponentId)
.Replace("{SharedFrameworkNugetName}", Monikers.SharedFrameworkName)
.Replace("{SharedFrameworkNugetVersion}", SharedFrameworkNugetVersion)
.Replace("{SharedFxBrandName}", Monikers.SharedFxBrandName)
.Replace("{SharedHostBrandName}", Monikers.SharedHostBrandName);
File.WriteAllText(distributionPath, formattedDistContents);
Cmd("productbuild",
"--version", SharedFrameworkNugetVersion,
"--identifier", SharedFxPkgId,
"--package-path", PkgsIntermediateDir,
"--resources", resourcePath,
"--distribution", distributionPath,
outFilePath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GenerateSharedFrameworkPkg(BuildTargetContext c)
{
string outFilePath = Path.Combine(PkgsIntermediateDir, SharedFxComponentId + ".pkg");
string installLocation = "/usr/local/share/dotnet";
string scriptsLocation = Path.Combine(Dirs.RepoRoot, "packaging", "osx", "sharedframework", "scripts");
Cmd("pkgbuild",
"--root", c.BuildContext.Get<string>("SharedFrameworkPublishRoot"),
"--identifier", SharedFxComponentId,
"--version", SharedFrameworkNugetVersion,
"--install-location", installLocation,
"--scripts", scriptsLocation,
outFilePath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.OSX)]
public static BuildTargetResult GenerateSharedHostPkg(BuildTargetContext c)
{
string version = c.BuildContext.Get<HostVersion>("HostVersion").LockedHostVersion;
string outFilePath = Path.Combine(PkgsIntermediateDir, SharedHostComponentId + ".pkg");
string installLocation = "/usr/local/share/dotnet";
string scriptsLocation = Path.Combine(Dirs.RepoRoot, "packaging", "osx", "sharedhost", "scripts");
Cmd("pkgbuild",
"--root", c.BuildContext.Get<string>("SharedHostPublishRoot"),
"--identifier", SharedHostComponentId,
"--version", version,
"--install-location", installLocation,
"--scripts", scriptsLocation,
outFilePath)
.Execute()
.EnsureSuccessful();
return c.Success();
}
}
}

View file

@ -0,0 +1,440 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using Newtonsoft.Json.Linq;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
using static Microsoft.DotNet.Cli.Build.FS;
using static Microsoft.DotNet.Cli.Build.Utils;
namespace Microsoft.DotNet.Cli.Build
{
public class PrepareTargets
{
[Target(nameof(Init))]
public static BuildTargetResult Prepare(BuildTargetContext c) => c.Success();
[Target(nameof(CheckPrereqCmakePresent), nameof(CheckPlatformDependencies))]
public static BuildTargetResult CheckPrereqs(BuildTargetContext c) => c.Success();
[Target(nameof(CheckCoreclrPlatformDependencies), nameof(CheckInstallerBuildPlatformDependencies))]
public static BuildTargetResult CheckPlatformDependencies(BuildTargetContext c) => c.Success();
[Target(nameof(CheckUbuntuCoreclrAndCoreFxDependencies), nameof(CheckCentOSCoreclrAndCoreFxDependencies))]
public static BuildTargetResult CheckCoreclrPlatformDependencies(BuildTargetContext c) => c.Success();
[Target(nameof(CheckUbuntuDebianPackageBuildDependencies))]
public static BuildTargetResult CheckInstallerBuildPlatformDependencies(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(UpdateTemplateVersions),
nameof(CheckPrereqs),
nameof(LocateStage0),
nameof(ExpectedBuildArtifacts),
nameof(RestorePackages))]
public static BuildTargetResult Init(BuildTargetContext c)
{
var configEnv = Environment.GetEnvironmentVariable("CONFIGURATION");
if (string.IsNullOrEmpty(configEnv))
{
configEnv = "Debug";
}
c.BuildContext["Configuration"] = configEnv;
c.BuildContext["Channel"] = Environment.GetEnvironmentVariable("CHANNEL");
c.Info($"Building {c.BuildContext["Configuration"]} to: {Dirs.Output}");
c.Info("Build Environment:");
c.Info($" Operating System: {RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}");
c.Info($" Platform: {RuntimeEnvironment.OperatingSystemPlatform}");
return c.Success();
}
[Target]
public static BuildTargetResult GenerateVersions(BuildTargetContext c)
{
var gitResult = Cmd("git", "rev-list", "--count", "HEAD")
.CaptureStdOut()
.Execute();
gitResult.EnsureSuccessful();
var commitCount = int.Parse(gitResult.StdOut);
gitResult = Cmd("git", "rev-parse", "HEAD")
.CaptureStdOut()
.Execute();
gitResult.EnsureSuccessful();
var commitHash = gitResult.StdOut.Trim();
var branchInfo = ReadBranchInfo(c, Path.Combine(c.BuildContext.BuildDirectory, "branchinfo.txt"));
var buildVersion = new BuildVersion()
{
Major = int.Parse(branchInfo["MAJOR_VERSION"]),
Minor = int.Parse(branchInfo["MINOR_VERSION"]),
Patch = int.Parse(branchInfo["PATCH_VERSION"]),
ReleaseSuffix = branchInfo["RELEASE_SUFFIX"],
CommitCount = commitCount
};
var hostVersion = new HostVersion()
{
CommitCount = commitCount
};
c.BuildContext["BuildVersion"] = buildVersion;
c.BuildContext["HostVersion"] = hostVersion;
c.BuildContext["CommitHash"] = commitHash;
c.BuildContext["SharedFrameworkNugetVersion"] = buildVersion.NetCoreAppVersion;
c.Info($"Building Version: {buildVersion.SimpleVersion} (NuGet Packages: {buildVersion.NuGetVersion})");
c.Info($"From Commit: {commitHash}");
return c.Success();
}
/// <summary>
/// Updates the Microsoft.NETCore.App version number in the `dotnet new` project.json.template files.
/// </summary>
[Target]
public static BuildTargetResult UpdateTemplateVersions(BuildTargetContext c)
{
IEnumerable<string> templateFiles = Directory.GetFiles(
Path.Combine(Dirs.RepoRoot, "src", "dotnet", "commands", "dotnet-new"),
"project.json.pretemplate",
SearchOption.AllDirectories);
foreach (string templateFile in templateFiles)
{
JObject projectRoot = JsonUtils.ReadProject(templateFile);
projectRoot["dependencies"]["Microsoft.NETCore.App"]["version"] = c.BuildContext.Get<BuildVersion>("BuildVersion").NetCoreAppVersion;
JsonUtils.WriteProject(projectRoot, Path.ChangeExtension(templateFile, "template"));
}
return c.Success();
}
[Target]
public static BuildTargetResult LocateStage0(BuildTargetContext c)
{
// We should have been run in the repo root, so locate the stage 0 relative to current directory
var stage0 = DotNetCli.Stage0.BinPath;
if (!Directory.Exists(stage0))
{
return c.Failed($"Stage 0 directory does not exist: {stage0}");
}
// Identify the version
string versionFile = Directory.GetFiles(stage0, ".version", SearchOption.AllDirectories).FirstOrDefault();
if (string.IsNullOrEmpty(versionFile))
{
throw new Exception($"'.version' file not found in '{stage0}' folder");
}
var version = File.ReadAllLines(versionFile);
c.Info($"Using Stage 0 Version: {version[1]}");
return c.Success();
}
[Target]
public static BuildTargetResult ExpectedBuildArtifacts(BuildTargetContext c)
{
var config = Environment.GetEnvironmentVariable("CONFIGURATION");
var versionBadgeName = $"{CurrentPlatform.Current}_{CurrentArchitecture.Current}_{config}_version_badge.svg";
c.BuildContext["VersionBadge"] = Path.Combine(Dirs.Output, versionBadgeName);
var cliVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
var sharedFrameworkVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
var hostVersion = c.BuildContext.Get<HostVersion>("HostVersion").LockedHostVersion;
AddInstallerArtifactToContext(c, "dotnet-sdk", "Sdk", cliVersion);
AddInstallerArtifactToContext(c, "dotnet-host", "SharedHost", hostVersion);
AddInstallerArtifactToContext(c, "dotnet-sharedframework", "SharedFramework", sharedFrameworkVersion);
AddInstallerArtifactToContext(c, "dotnet-dev", "CombinedFrameworkSDKHost", cliVersion);
AddInstallerArtifactToContext(c, "dotnet", "CombinedFrameworkHost", sharedFrameworkVersion);
AddInstallerArtifactToContext(c, "dotnet-sharedframework-sdk", "CombinedFrameworkSDK", cliVersion);
AddInstallerArtifactToContext(c, "dotnet-sdk-debug", "SdkSymbols", cliVersion);
return c.Success();
}
[Target]
public static BuildTargetResult CheckPackageCache(BuildTargetContext c)
{
var ciBuild = string.Equals(Environment.GetEnvironmentVariable("CI_BUILD"), "1", StringComparison.Ordinal);
if (ciBuild)
{
// On CI, HOME is redirected under the repo, which gets deleted after every build.
// So make NUGET_PACKAGES outside of the repo.
var nugetPackages = Path.GetFullPath(Path.Combine(c.BuildContext.BuildDirectory, "..", ".nuget", "packages"));
Environment.SetEnvironmentVariable("NUGET_PACKAGES", nugetPackages);
Dirs.NuGetPackages = nugetPackages;
}
// Set the package cache location in NUGET_PACKAGES just to be safe
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NUGET_PACKAGES")))
{
Environment.SetEnvironmentVariable("NUGET_PACKAGES", Dirs.NuGetPackages);
}
CleanNuGetTempCache();
// Determine cache expiration time
var cacheExpiration = 7 * 24; // cache expiration in hours
var cacheExpirationStr = Environment.GetEnvironmentVariable("NUGET_PACKAGES_CACHE_TIME_LIMIT");
if (!string.IsNullOrEmpty(cacheExpirationStr))
{
cacheExpiration = int.Parse(cacheExpirationStr);
}
if (ciBuild)
{
var cacheTimeFile = Path.Combine(Dirs.NuGetPackages, "packageCacheTime.txt");
DateTime? cacheTime = null;
try
{
// Read the cache file
if (File.Exists(cacheTimeFile))
{
var content = File.ReadAllText(cacheTimeFile);
if (!string.IsNullOrEmpty(content))
{
cacheTime = DateTime.ParseExact("O", content, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
}
}
catch (Exception ex)
{
c.Warn($"Error reading NuGet cache time file, leaving the cache alone");
c.Warn($"Error Detail: {ex.ToString()}");
}
if (cacheTime == null || (cacheTime.Value.AddHours(cacheExpiration) < DateTime.UtcNow))
{
// Cache has expired or the status is unknown, clear it and write the file
c.Info("Clearing NuGet cache");
Rmdir(Dirs.NuGetPackages);
Mkdirp(Dirs.NuGetPackages);
File.WriteAllText(cacheTimeFile, DateTime.UtcNow.ToString("O"));
}
}
return c.Success();
}
[Target(nameof(CheckPackageCache))]
public static BuildTargetResult RestorePackages(BuildTargetContext c)
{
var dotnet = DotNetCli.Stage0;
dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--fallbacksource", Dirs.CorehostLocalPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "src"))
.Execute()
.EnsureSuccessful();
dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes")
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools"))
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult CheckUbuntuDebianPackageBuildDependencies(BuildTargetContext c)
{
var messageBuilder = new StringBuilder();
var aptDependencyUtility = new AptDependencyUtility();
foreach (var package in PackageDependencies.DebianPackageBuildDependencies)
{
if (!AptDependencyUtility.PackageIsInstalled(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]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult CheckUbuntuCoreclrAndCoreFxDependencies(BuildTargetContext c)
{
var errorMessageBuilder = new StringBuilder();
var stage0 = DotNetCli.Stage0.BinPath;
foreach (var package in PackageDependencies.UbuntuCoreclrAndCoreFxDependencies)
{
if (!AptDependencyUtility.PackageIsInstalled(package))
{
errorMessageBuilder.Append($"Error: Coreclr package dependency {package} missing.");
errorMessageBuilder.Append(Environment.NewLine);
errorMessageBuilder.Append($"-> install with apt-get install {package}");
errorMessageBuilder.Append(Environment.NewLine);
}
}
if (errorMessageBuilder.Length == 0)
{
return c.Success();
}
else
{
return c.Failed(errorMessageBuilder.ToString());
}
}
[Target]
[BuildPlatforms(BuildPlatform.CentOS)]
public static BuildTargetResult CheckCentOSCoreclrAndCoreFxDependencies(BuildTargetContext c)
{
var errorMessageBuilder = new StringBuilder();
foreach (var package in PackageDependencies.CentosCoreclrAndCoreFxDependencies)
{
if (!YumDependencyUtility.PackageIsInstalled(package))
{
errorMessageBuilder.Append($"Error: Coreclr package dependency {package} missing.");
errorMessageBuilder.Append(Environment.NewLine);
errorMessageBuilder.Append($"-> install with yum install {package}");
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 string GetVersionFromProjectJson(string pathToProjectJson)
{
Regex r = new Regex($"\"{Regex.Escape(Monikers.SharedFrameworkName)}\"\\s*:\\s*\"(?'version'[^\"]*)\"");
foreach (var line in File.ReadAllLines(pathToProjectJson))
{
var m = r.Match(line);
if (m.Success)
{
return m.Groups["version"].Value;
}
}
throw new InvalidOperationException("Unable to match the version name from " + pathToProjectJson);
}
private static IDictionary<string, string> ReadBranchInfo(BuildTargetContext c, string path)
{
var lines = File.ReadAllLines(path);
var dict = new Dictionary<string, string>();
c.Verbose("Branch Info:");
foreach (var line in lines)
{
if (!line.Trim().StartsWith("#") && !string.IsNullOrWhiteSpace(line))
{
var splat = line.Split(new[] { '=' }, 2);
dict[splat[0]] = splat[1];
c.Verbose($" {splat[0]} = {splat[1]}");
}
}
return dict;
}
private static void AddInstallerArtifactToContext(
BuildTargetContext c,
string artifactPrefix,
string contextPrefix,
string version)
{
var productName = Monikers.GetProductMoniker(c, artifactPrefix, version);
var extension = CurrentPlatform.IsWindows ? ".zip" : ".tar.gz";
c.BuildContext[contextPrefix + "CompressedFile"] = Path.Combine(Dirs.Packages, productName + extension);
string installer = "";
switch (CurrentPlatform.Current)
{
case BuildPlatform.Windows:
installer = productName + ".exe";
break;
case BuildPlatform.OSX:
installer = productName + ".pkg";
break;
case BuildPlatform.Ubuntu:
installer = productName + ".deb";
break;
default:
break;
}
if (!string.IsNullOrEmpty(installer))
{
c.BuildContext[contextPrefix + "InstallerFile"] = Path.Combine(Dirs.Packages, installer);
}
}
}
}

View file

@ -0,0 +1,17 @@
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public class Program
{
public static int Main(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
return BuildSetup.Create(".NET Core CLI")
.UseStandardGoals()
.UseAllTargetsFromAssembly<Program>()
.Run(args);
}
}
}

View file

@ -0,0 +1,555 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public static class PublishTargets
{
private static AzurePublisher AzurePublisherTool { get; set; }
private static DebRepoPublisher DebRepoPublisherTool { get; set; }
private static string Channel { get; set; }
private static string CliVersion { get; set; }
private static string CliNuGetVersion { get; set; }
private static string SharedFrameworkNugetVersion { get; set; }
private static string SharedHostNugetVersion { get; set; }
[Target]
public static BuildTargetResult InitPublish(BuildTargetContext c)
{
AzurePublisherTool = new AzurePublisher();
DebRepoPublisherTool = new DebRepoPublisher(Dirs.Packages);
CliVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").SimpleVersion;
CliNuGetVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
SharedFrameworkNugetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
SharedHostNugetVersion = c.BuildContext.Get<HostVersion>("HostVersion").LockedHostVersion;
Channel = c.BuildContext.Get<string>("Channel");
return c.Success();
}
[Target(nameof(PrepareTargets.Init),
nameof(PublishTargets.InitPublish),
nameof(PublishTargets.PublishArtifacts),
nameof(PublishTargets.TriggerDockerHubBuilds),
nameof(PublishTargets.FinalizeBuild))]
[Environment("PUBLISH_TO_AZURE_BLOB", "1", "true")] // This is set by CI systems
public static BuildTargetResult Publish(BuildTargetContext c)
{
return c.Success();
}
[Target]
public static BuildTargetResult FinalizeBuild(BuildTargetContext c)
{
if (CheckIfAllBuildsHavePublished())
{
string targetContainer = $"{Channel}/Binaries/Latest/";
string targetVersionFile = $"{targetContainer}{CliNuGetVersion}";
string semaphoreBlob = $"{Channel}/Binaries/publishSemaphore";
AzurePublisherTool.CreateBlobIfNotExists(semaphoreBlob);
string leaseId = AzurePublisherTool.AcquireLeaseOnBlob(semaphoreBlob);
// Prevent race conditions by dropping a version hint of what version this is. If we see this file
// and it is the same as our version then we know that a race happened where two+ builds finished
// at the same time and someone already took care of publishing and we have no work to do.
if (AzurePublisherTool.IsLatestSpecifiedVersion(targetVersionFile))
{
AzurePublisherTool.ReleaseLeaseOnBlob(semaphoreBlob, leaseId);
return c.Success();
}
else
{
// This is an old drop of latest so remove all old files to ensure a clean state
AzurePublisherTool.ListBlobs($"{targetContainer}")
.Select(s => s.Replace("/dotnet/", ""))
.ToList()
.ForEach(f => AzurePublisherTool.TryDeleteBlob(f));
// Drop the version file signaling such for any race-condition builds (see above comment).
AzurePublisherTool.DropLatestSpecifiedVersion(targetVersionFile);
}
try
{
// Copy the latest CLI bits
CopyBlobs($"{Channel}/Binaries/{CliNuGetVersion}/", targetContainer);
// Copy the shared framework
CopyBlobs($"{Channel}/Binaries/{SharedFrameworkNugetVersion}/", targetContainer);
// Copy the latest installer files
CopyBlobs($"{Channel}/Installers/{CliNuGetVersion}/", $"{Channel}/Installers/Latest/");
// Copy the shared framework installers
CopyBlobs($"{Channel}/Installers/{SharedFrameworkNugetVersion}/", $"{Channel}/Installers/Latest/");
// Copy the shared host installers
CopyBlobs($"{Channel}/Installers/{SharedHostNugetVersion}/", $"{Channel}/Installers/Latest/");
// Generate the CLI and SDK Version text files
List<string> versionFiles = new List<string>() { "win.x86.version", "win.x64.version", "ubuntu.x64.version", "rhel.x64.version", "osx.x64.version", "debian.x64.version", "centos.x64.version" };
string cliVersion = Utils.GetCliVersionFileContent(c);
string sfxVersion = Utils.GetSharedFrameworkVersionFileContent(c);
foreach (string version in versionFiles)
{
AzurePublisherTool.PublishStringToBlob($"{Channel}/dnvm/latest.{version}", cliVersion);
AzurePublisherTool.PublishStringToBlob($"{Channel}/dnvm/latest.sharedfx.{version}", sfxVersion);
}
}
finally
{
AzurePublisherTool.ReleaseLeaseOnBlob(semaphoreBlob, leaseId);
}
}
return c.Success();
}
private static void CopyBlobs(string sourceFolder, string destinationFolder)
{
foreach (string blob in AzurePublisherTool.ListBlobs(sourceFolder))
{
string source = blob.Replace("/dotnet/", "");
string targetName = Path.GetFileName(blob)
.Replace(CliNuGetVersion, "latest")
.Replace(SharedFrameworkNugetVersion, "latest")
.Replace(SharedHostNugetVersion, "latest");
string target = $"{destinationFolder}{targetName}";
AzurePublisherTool.CopyBlob(source, target);
}
}
private static bool CheckIfAllBuildsHavePublished()
{
Dictionary<string, bool> badges = new Dictionary<string, bool>()
{
{ "Windows_x86", false },
{ "Windows_x64", false },
{ "Ubuntu_x64", false },
{ "RHEL_x64", false },
{ "OSX_x64", false },
{ "Debian_x64", false },
{ "CentOS_x64", false }
};
List<string> blobs = new List<string>(AzurePublisherTool.ListBlobs($"{Channel}/Binaries/{CliNuGetVersion}/"));
var config = Environment.GetEnvironmentVariable("CONFIGURATION");
var versionBadgeName = $"{CurrentPlatform.Current}_{CurrentArchitecture.Current}";
if (badges.ContainsKey(versionBadgeName) == false)
{
throw new ArgumentException("A new OS build was added without adding the moniker to the {nameof(badges)} lookup");
}
foreach (string file in blobs)
{
string name = Path.GetFileName(file);
string key = string.Empty;
foreach (string img in badges.Keys)
{
if ((name.StartsWith($"{img}")) && (name.EndsWith(".svg")))
{
key = img;
break;
}
}
if (string.IsNullOrEmpty(key) == false)
{
badges[key] = true;
}
}
return badges.Keys.All(key => badges[key]);
}
[Target(
nameof(PublishTargets.PublishInstallerFilesToAzure),
nameof(PublishTargets.PublishArchivesToAzure),
/*nameof(PublishTargets.PublishDebFilesToDebianRepo),*/ //https://github.com/dotnet/cli/issues/2973
nameof(PublishTargets.PublishCoreHostPackages),
nameof(PublishTargets.PublishCliVersionBadge))]
public static BuildTargetResult PublishArtifacts(BuildTargetContext c) => c.Success();
[Target(
nameof(PublishTargets.PublishSharedHostInstallerFileToAzure),
nameof(PublishTargets.PublishSharedFrameworkInstallerFileToAzure),
nameof(PublishTargets.PublishSdkInstallerFileToAzure),
nameof(PublishTargets.PublishCombinedFrameworkSDKHostInstallerFileToAzure),
nameof(PublishTargets.PublishCombinedFrameworkHostInstallerFileToAzure))]
public static BuildTargetResult PublishInstallerFilesToAzure(BuildTargetContext c) => c.Success();
[Target(
nameof(PublishTargets.PublishCombinedHostFrameworkArchiveToAzure),
nameof(PublishTargets.PublishCombinedHostFrameworkSdkArchiveToAzure),
nameof(PublishTargets.PublishCombinedFrameworkSDKArchiveToAzure),
nameof(PublishTargets.PublishSDKSymbolsArchiveToAzure))]
public static BuildTargetResult PublishArchivesToAzure(BuildTargetContext c) => c.Success();
[Target(
nameof(PublishSdkDebToDebianRepo),
nameof(PublishSharedFrameworkDebToDebianRepo),
nameof(PublishSharedHostDebToDebianRepo))]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishDebFilesToDebianRepo(BuildTargetContext c)
{
return c.Success();
}
[Target]
public static BuildTargetResult PublishCliVersionBadge(BuildTargetContext c)
{
var versionBadge = c.BuildContext.Get<string>("VersionBadge");
var versionBadgeBlob = $"{Channel}/Binaries/{CliNuGetVersion}/{Path.GetFileName(versionBadge)}";
AzurePublisherTool.PublishFile(versionBadgeBlob, versionBadge);
return c.Success();
}
[Target]
public static BuildTargetResult PublishCoreHostPackages(BuildTargetContext c)
{
foreach (var file in Directory.GetFiles(Dirs.CorehostLocalPackages, "*.nupkg"))
{
var hostBlob = $"{Channel}/Binaries/{SharedFrameworkNugetVersion}/{Path.GetFileName(file)}";
AzurePublisherTool.PublishFile(hostBlob, file);
Console.WriteLine($"Publishing package {hostBlob} to Azure.");
}
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu, BuildPlatform.Windows)]
public static BuildTargetResult PublishSharedHostInstallerFileToAzure(BuildTargetContext c)
{
var version = SharedHostNugetVersion;
var installerFile = c.BuildContext.Get<string>("SharedHostInstallerFile");
if (CurrentPlatform.Current == BuildPlatform.Windows)
{
installerFile = Path.ChangeExtension(installerFile, "msi");
}
AzurePublisherTool.PublishInstallerFile(installerFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishSharedFrameworkInstallerFileToAzure(BuildTargetContext c)
{
var version = SharedFrameworkNugetVersion;
var installerFile = c.BuildContext.Get<string>("SharedFrameworkInstallerFile");
AzurePublisherTool.PublishInstallerFile(installerFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishSdkInstallerFileToAzure(BuildTargetContext c)
{
var version = CliNuGetVersion;
var installerFile = c.BuildContext.Get<string>("SdkInstallerFile");
AzurePublisherTool.PublishInstallerFile(installerFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows, BuildPlatform.OSX)]
public static BuildTargetResult PublishCombinedFrameworkHostInstallerFileToAzure(BuildTargetContext c)
{
var version = SharedFrameworkNugetVersion;
var installerFile = c.BuildContext.Get<string>("CombinedFrameworkHostInstallerFile");
AzurePublisherTool.PublishInstallerFile(installerFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows, BuildPlatform.OSX)]
public static BuildTargetResult PublishCombinedFrameworkSDKHostInstallerFileToAzure(BuildTargetContext c)
{
var version = CliNuGetVersion;
var installerFile = c.BuildContext.Get<string>("CombinedFrameworkSDKHostInstallerFile");
AzurePublisherTool.PublishInstallerFile(installerFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult PublishCombinedFrameworkSDKArchiveToAzure(BuildTargetContext c)
{
var version = CliNuGetVersion;
var archiveFile = c.BuildContext.Get<string>("CombinedFrameworkSDKCompressedFile");
AzurePublisherTool.PublishArchive(archiveFile, Channel, version);
return c.Success();
}
[Target]
public static BuildTargetResult PublishCombinedHostFrameworkSdkArchiveToAzure(BuildTargetContext c)
{
var version = CliNuGetVersion;
var archiveFile = c.BuildContext.Get<string>("CombinedFrameworkSDKHostCompressedFile");
AzurePublisherTool.PublishArchive(archiveFile, Channel, version);
return c.Success();
}
[Target]
public static BuildTargetResult PublishSDKSymbolsArchiveToAzure(BuildTargetContext c)
{
var version = CliNuGetVersion;
var archiveFile = c.BuildContext.Get<string>("SdkSymbolsCompressedFile");
AzurePublisherTool.PublishArchive(archiveFile, Channel, version);
return c.Success();
}
[Target]
public static BuildTargetResult PublishCombinedHostFrameworkArchiveToAzure(BuildTargetContext c)
{
var version = SharedFrameworkNugetVersion;
var archiveFile = c.BuildContext.Get<string>("CombinedFrameworkHostCompressedFile");
AzurePublisherTool.PublishArchive(archiveFile, Channel, version);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishSdkDebToDebianRepo(BuildTargetContext c)
{
var version = CliNuGetVersion;
var packageName = Monikers.GetSdkDebianPackageName(c);
var installerFile = c.BuildContext.Get<string>("SdkInstallerFile");
var uploadUrl = AzurePublisherTool.CalculateInstallerUploadUrl(installerFile, Channel, version);
DebRepoPublisherTool.PublishDebFileToDebianRepo(
packageName,
version,
uploadUrl);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishSharedFrameworkDebToDebianRepo(BuildTargetContext c)
{
var version = SharedFrameworkNugetVersion;
var packageName = Monikers.GetDebianSharedFrameworkPackageName(c);
var installerFile = c.BuildContext.Get<string>("SharedFrameworkInstallerFile");
var uploadUrl = AzurePublisherTool.CalculateInstallerUploadUrl(installerFile, Channel, version);
DebRepoPublisherTool.PublishDebFileToDebianRepo(
packageName,
version,
uploadUrl);
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Ubuntu)]
public static BuildTargetResult PublishSharedHostDebToDebianRepo(BuildTargetContext c)
{
var version = SharedHostNugetVersion;
var packageName = Monikers.GetDebianSharedHostPackageName(c);
var installerFile = c.BuildContext.Get<string>("SharedHostInstallerFile");
var uploadUrl = AzurePublisherTool.CalculateInstallerUploadUrl(installerFile, Channel, version);
DebRepoPublisherTool.PublishDebFileToDebianRepo(
packageName,
version,
uploadUrl);
return c.Success();
}
[Target]
[Environment("DOCKER_HUB_REPO")]
[Environment("DOCKER_HUB_TRIGGER_TOKEN")]
public static BuildTargetResult TriggerDockerHubBuilds(BuildTargetContext c)
{
string dockerHubRepo = Environment.GetEnvironmentVariable("DOCKER_HUB_REPO");
string dockerHubTriggerToken = Environment.GetEnvironmentVariable("DOCKER_HUB_TRIGGER_TOKEN");
Uri baseDockerHubUri = new Uri("https://registry.hub.docker.com/u/");
Uri dockerHubTriggerUri;
if (!Uri.TryCreate(baseDockerHubUri, $"{dockerHubRepo}/trigger/{dockerHubTriggerToken}/", out dockerHubTriggerUri))
{
return c.Failed("Invalid DOCKER_HUB_REPO and/or DOCKER_HUB_TRIGGER_TOKEN");
}
c.Info($"Triggering automated DockerHub builds for {dockerHubRepo}");
using (HttpClient client = new HttpClient())
{
StringContent requestContent = new StringContent("{\"build\": true}", Encoding.UTF8, "application/json");
try
{
HttpResponseMessage response = client.PostAsync(dockerHubTriggerUri, requestContent).Result;
if (!response.IsSuccessStatusCode)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"HTTP request to {dockerHubTriggerUri.ToString()} was unsuccessful.");
sb.AppendLine($"Response status code: {response.StatusCode}. Reason phrase: {response.ReasonPhrase}.");
sb.Append($"Respone content: {response.Content.ReadAsStringAsync().Result}");
return c.Failed(sb.ToString());
}
}
catch (AggregateException e)
{
return c.Failed($"HTTP request to {dockerHubTriggerUri.ToString()} failed. {e.ToString()}");
}
}
return c.Success();
}
private const string PackagePushedSemaphoreFileName = "packages.pushed";
[Target(nameof(PrepareTargets.Init), nameof(InitPublish))]
public static BuildTargetResult PullNupkgFilesFromBlob(BuildTargetContext c)
{
Directory.CreateDirectory(Dirs.PackagesNoRID);
var hostBlob = $"{Channel}/Binaries/";
string forcePushBuild = Environment.GetEnvironmentVariable("FORCE_PUBLISH_BLOB_BUILD_VERSION");
if (!string.IsNullOrEmpty(forcePushBuild))
{
Console.WriteLine($"Forcing all nupkg packages for build version {forcePushBuild}.");
DownloadPackagesForPush(hostBlob + forcePushBuild);
return c.Success();
}
List<string> buildVersions = new List<string>();
Regex buildVersionRegex = new Regex(@"Binaries/(?<version>\d+\.\d+\.\d+(?<prerelease>-[^-]+-\d{6})?)/$");
foreach (string file in AzurePublisherTool.ListBlobs(hostBlob))
{
var match = buildVersionRegex.Match(file);
if (match.Success)
{
buildVersions.Add(match.Groups["version"].Value);
}
}
// Sort decending
buildVersions.Sort();
buildVersions.Reverse();
// Try to publish the last 10 builds
foreach (var bv in buildVersions.Take(10))
{
Console.WriteLine($"Checking drop version: {bv}");
if (ShouldDownloadAndPush(hostBlob, bv))
{
DownloadPackagesForPush(hostBlob + bv);
}
}
return c.Success();
}
private static bool ShouldDownloadAndPush(string hostBlob, string buildVersion)
{
// Set of runtime ids to look for to act as the signal that the build
// as finished each of these legs of the build.
Dictionary<string, bool> runtimes = new Dictionary<string, bool>()
{
{"win7-x64", false },
{"win7-x86", false },
{"osx.10.10-x64", false },
{"rhel.7-x64", false },
{"ubuntu.14.04-x64", false },
{"debian.8-x64", false },
};
var buildFiles = AzurePublisherTool.ListBlobs(hostBlob + buildVersion);
foreach (var bf in buildFiles)
{
string buildFile = Path.GetFileName(bf);
if (buildFile == PackagePushedSemaphoreFileName)
{
Console.WriteLine($"Found '{PackagePushedSemaphoreFileName}' for build version {buildVersion} so skipping this drop.");
// Nothing to do because the latest build is uploaded.
return false;
}
foreach (var runtime in runtimes.Keys)
{
if (buildFile.StartsWith($"runtime.{runtime}"))
{
runtimes[runtime] = true;
break;
}
}
}
bool missingRuntime = false;
foreach (var runtime in runtimes)
{
if (!runtime.Value)
{
missingRuntime = true;
Console.WriteLine($"Version {buildVersion} missing packages for runtime {runtime.Key}");
}
}
if (missingRuntime)
{
Console.WriteLine($"Build version {buildVersion} is missing some runtime packages so not pushing this drop.");
}
return !missingRuntime;
}
private static void DownloadPackagesForPush(string pathToDownload)
{
AzurePublisherTool.DownloadFiles(pathToDownload, ".nupkg", Dirs.PackagesNoRID);
string pushedSemaphore = Path.Combine(Dirs.PackagesNoRID, PackagePushedSemaphoreFileName);
File.WriteAllText(pushedSemaphore, $"Packages pushed for build {pathToDownload}");
AzurePublisherTool.PublishFile(pathToDownload + "/" + PackagePushedSemaphoreFileName, pushedSemaphore);
}
}
}

View file

@ -0,0 +1,222 @@
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public static class TestPackageProjects
{
public class TestPackageProject
{
public string Name { get; set; }
public bool IsTool { get; set; }
public string Path { get; set; }
public bool IsApplicable { get; set; }
public string VersionSuffix { get; set; }
public bool Clean { get; set; }
public string[] Frameworks { get; set; }
}
private static string s_testPackageBuildVersionSuffix = "<buildversion>";
public static string TestPackageBuildVersionSuffix
{
get
{
return s_testPackageBuildVersionSuffix;
}
}
public static readonly TestPackageProject[] Projects = new[]
{
new TestPackageProject()
{
Name = "PackageWithFakeNativeDep",
IsTool = false,
Path = "TestAssets/TestPackages/PackageWithFakeNativeDep",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "net45" }
},
new TestPackageProject()
{
Name = "dotnet-dependency-context-test",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-dependency-context-test",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "dotnet-dependency-tool-invoker",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "dotnet-desktop-and-portable",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-desktop-and-portable",
IsApplicable = CurrentPlatform.IsWindows,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "net451", "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "dotnet-desktop-binding-redirects",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-desktop-binding-redirects",
IsApplicable = CurrentPlatform.IsWindows,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "net451" }
},
new TestPackageProject()
{
Name = "dotnet-hello",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-hello/v1/dotnet-hello",
IsApplicable =true,
VersionSuffix = string.Empty,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "dotnet-hello",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-hello/v2/dotnet-hello",
IsApplicable = true,
VersionSuffix = string.Empty,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "dotnet-portable",
IsTool = true,
Path = "TestAssets/TestPackages/dotnet-portable",
IsApplicable = true,
VersionSuffix = string.Empty,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "ToolWithOutputName",
IsTool = true,
Path = "TestAssets/TestPackages/ToolWithOutputName",
IsApplicable = true,
VersionSuffix = string.Empty,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.Cli.Utils",
IsTool = true,
Path = "src/Microsoft.DotNet.Cli.Utils",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "net451", "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.ProjectModel",
IsTool = true,
Path = "src/Microsoft.DotNet.ProjectModel",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "net451", "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.ProjectModel.Loader",
IsTool = true,
Path = "src/Microsoft.DotNet.ProjectModel.Loader",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.ProjectModel.Workspaces",
IsTool = true,
Path = "src/Microsoft.DotNet.ProjectModel.Workspaces",
IsApplicable =true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.InternalAbstractions",
IsTool = true,
Path = "src/Microsoft.DotNet.InternalAbstractions",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "net451", "netstandard1.3" }
},
new TestPackageProject()
{
Name = "Microsoft.Extensions.DependencyModel",
IsTool = true,
Path = "src/Microsoft.Extensions.DependencyModel",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "net451", "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.Extensions.Testing.Abstractions",
IsTool = true,
Path = "src/Microsoft.Extensions.Testing.Abstractions",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "net451", "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.Compiler.Common",
IsTool = true,
Path = "src/Microsoft.DotNet.Compiler.Common",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "netstandard1.5" }
},
new TestPackageProject()
{
Name = "Microsoft.DotNet.Files",
IsTool = true,
Path = "src/Microsoft.DotNet.Files",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = false,
Frameworks = new [] { "netstandard1.5" }
},
new TestPackageProject()
{
Name = "dotnet-compile-fsc",
IsTool = true,
Path = "src/dotnet-compile-fsc",
IsApplicable = true,
VersionSuffix = s_testPackageBuildVersionSuffix,
Clean = true,
Frameworks = new [] { "netcoreapp1.0" }
}
};
}
}

View file

@ -0,0 +1,456 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using static Microsoft.DotNet.Cli.Build.FS;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
using static Microsoft.DotNet.Cli.Build.Utils;
namespace Microsoft.DotNet.Cli.Build
{
public class TestTargets
{
private static string s_testPackageBuildVersionSuffix = "<buildversion>";
public static readonly string[] TestProjects = new[]
{
"ArgumentForwardingTests",
"crossgen.Tests",
"EndToEnd",
"dotnet.Tests",
"dotnet-build.Tests",
"dotnet-compile.Tests",
"dotnet-compile.UnitTests",
"dotnet-compile-fsc.Tests",
"dotnet-new.Tests",
"dotnet-pack.Tests",
"dotnet-projectmodel-server.Tests",
"dotnet-publish.Tests",
"dotnet-resgen.Tests",
"dotnet-run.Tests",
"dotnet-run.UnitTests",
"dotnet-test.Tests",
"dotnet-test.UnitTests",
"Kestrel.Tests",
"Microsoft.DotNet.Cli.Utils.Tests",
"Microsoft.DotNet.Compiler.Common.Tests",
"Microsoft.DotNet.ProjectModel.Tests",
"Microsoft.Extensions.DependencyModel.Tests",
"Performance"
};
public static readonly string[] WindowsTestProjects = new[]
{
"binding-redirects.Tests"
};
public static readonly dynamic[] ConditionalTestAssets = new[]
{
new { Path = "AppWithDirectDependencyDesktopAndPortable", Skip = new Func<bool>(() => !CurrentPlatform.IsWindows) }
};
[Target(
nameof(PrepareTargets.Init),
nameof(SetupTests),
nameof(RestoreTests),
nameof(BuildTests),
nameof(RunTests),
nameof(ValidateDependencies))]
public static BuildTargetResult Test(BuildTargetContext c) => c.Success();
[Target(nameof(SetupTestPackages), nameof(SetupTestProjects))]
public static BuildTargetResult SetupTests(BuildTargetContext c) => c.Success();
[Target(nameof(RestoreTestAssetPackages), nameof(BuildTestAssetPackages))]
public static BuildTargetResult SetupTestPackages(BuildTargetContext c) => c.Success();
[Target(nameof(RestoreTestAssetProjects),
nameof(RestoreDesktopTestAssetProjects),
nameof(BuildTestAssetProjects),
nameof(BuildDesktopTestAssetProjects))]
public static BuildTargetResult SetupTestProjects(BuildTargetContext c) => c.Success();
[Target]
public static BuildTargetResult RestoreTestAssetPackages(BuildTargetContext c)
{
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
CleanNuGetTempCache();
var dotnet = DotNetCli.Stage2;
dotnet.Restore("--verbosity", "verbose",
"--infer-runtimes",
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages"))
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
public static BuildTargetResult RestoreTestAssetProjects(BuildTargetContext c)
{
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
CleanNuGetTempCache();
var dotnet = DotNetCli.Stage2;
dotnet.Restore(
"--verbosity", "verbose",
"--infer-runtimes",
"--fallbacksource", Dirs.TestPackages,
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestProjects"))
.Execute()
.EnsureSuccessful();
// The 'ProjectModelServer' directory contains intentionally-unresolved dependencies, so don't check for success. Also, suppress the output
dotnet.Restore(
"--verbosity", "verbose",
"--infer-runtimes",
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "ProjectModelServer", "DthTestProjects"))
.Execute();
dotnet.Restore(
"--verbosity", "verbose",
"--infer-runtimes")
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "ProjectModelServer", "DthUpdateSearchPathSample"))
.Execute();
return c.Success();
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult RestoreDesktopTestAssetProjects(BuildTargetContext c)
{
var dotnet = DotNetCli.Stage2;
dotnet.Restore("--verbosity", "verbose",
"--infer-runtimes",
"--fallbacksource", Dirs.TestPackages,
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "DesktopTestProjects"))
.Execute().EnsureSuccessful();
return c.Success();
}
[Target(nameof(CleanTestPackages), nameof(CleanProductPackages))]
public static BuildTargetResult BuildTestAssetPackages(BuildTargetContext c)
{
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages"));
var dotnet = DotNetCli.Stage2;
Rmdir(Dirs.TestPackages);
Mkdirp(Dirs.TestPackages);
foreach (var testPackageProject in TestPackageProjects.Projects.Where(p => p.IsApplicable))
{
var relativePath = testPackageProject.Path;
var versionSuffix = testPackageProject.VersionSuffix;
if (versionSuffix.Equals(s_testPackageBuildVersionSuffix))
{
versionSuffix = c.BuildContext.Get<BuildVersion>("BuildVersion").CommitCountString;
}
var fullPath = Path.Combine(c.BuildContext.BuildDirectory, relativePath.Replace('/', Path.DirectorySeparatorChar));
c.Info($"Packing: {fullPath}");
var packageBuildFrameworks = testPackageProject.Frameworks.ToList();
if (!CurrentPlatform.IsWindows)
{
packageBuildFrameworks.RemoveAll(f => f.StartsWith("net4"));
}
foreach (var packageBuildFramework in packageBuildFrameworks)
{
var buildArgs = new List<string>();
buildArgs.Add("-f");
buildArgs.Add(packageBuildFramework);
buildArgs.Add("--build-base-path");
buildArgs.Add(Dirs.TestPackagesBuild);
buildArgs.Add(fullPath);
Mkdirp(Dirs.TestPackagesBuild);
dotnet.Build(buildArgs.ToArray())
.Execute()
.EnsureSuccessful();
}
var projectJson = Path.Combine(fullPath, "project.json");
var dotnetPackArgs = new List<string> {
projectJson,
"--no-build",
"--build-base-path", Dirs.TestPackagesBuild,
"--output", Dirs.TestPackages
};
if (!string.IsNullOrEmpty(versionSuffix))
{
dotnetPackArgs.Add("--version-suffix");
dotnetPackArgs.Add(versionSuffix);
}
dotnet.Pack(dotnetPackArgs.ToArray())
.Execute()
.EnsureSuccessful();
}
return c.Success();
}
[Target]
public static BuildTargetResult CleanProductPackages(BuildTargetContext c)
{
foreach (var packageName in PackageTargets.ProjectsToPack)
{
Rmdir(Path.Combine(Dirs.NuGetPackages, packageName));
}
return c.Success();
}
[Target]
public static BuildTargetResult CleanTestPackages(BuildTargetContext c)
{
foreach (var packageProject in TestPackageProjects.Projects.Where(p => p.IsApplicable && p.Clean))
{
Rmdir(Path.Combine(Dirs.NuGetPackages, packageProject.Name));
if (packageProject.IsTool)
{
Rmdir(Path.Combine(Dirs.NuGetPackages, ".tools", packageProject.Name));
}
}
return c.Success();
}
[Target]
public static BuildTargetResult BuildTestAssetProjects(BuildTargetContext c)
{
var testAssetsRoot = Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestProjects");
var dotnet = DotNetCli.Stage2;
var framework = "netcoreapp1.0";
return BuildTestAssets(c, testAssetsRoot, dotnet, framework);
}
[Target]
[BuildPlatforms(BuildPlatform.Windows)]
public static BuildTargetResult BuildDesktopTestAssetProjects(BuildTargetContext c)
{
var testAssetsRoot = Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "DesktopTestProjects");
var dotnet = DotNetCli.Stage2;
var framework = "net451";
return BuildTestAssets(c, testAssetsRoot, dotnet, framework);
}
[Target]
public static BuildTargetResult RestoreTests(BuildTargetContext c)
{
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
CleanNuGetTempCache();
DotNetCli.Stage2.Restore("--verbosity", "verbose",
"--fallbacksource", Dirs.TestPackages,
"--fallbacksource", Dirs.CorehostLocalPackages,
"--fallbacksource", Dirs.CorehostDummyPackages)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test"))
.Execute()
.EnsureSuccessful();
return c.Success();
}
[Target]
public static BuildTargetResult BuildTests(BuildTargetContext c)
{
var dotnet = DotNetCli.Stage2;
var configuration = c.BuildContext.Get<string>("Configuration");
foreach (var testProject in GetTestProjects())
{
c.Info($"Building tests: {testProject}");
dotnet.Build("--configuration", configuration)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test", testProject))
.Execute()
.EnsureSuccessful();
}
return c.Success();
}
[Target(nameof(RunXUnitTests))]
public static BuildTargetResult RunTests(BuildTargetContext c) => c.Success();
[Target]
public static BuildTargetResult RunXUnitTests(BuildTargetContext c)
{
// Need to load up the VS Vars
var dotnet = DotNetCli.Stage2;
var vsvars = LoadVsVars(c);
var configuration = c.BuildContext.Get<string>("Configuration");
// Copy the test projects
var testProjectsDir = Path.Combine(Dirs.TestOutput, "TestProjects");
Rmdir(testProjectsDir);
Mkdirp(testProjectsDir);
CopyRecursive(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestProjects"), testProjectsDir);
// Run the tests and set the VS vars in the environment when running them
var failingTests = new List<string>();
foreach (var project in GetTestProjects())
{
c.Info($"Running tests in: {project}");
var result = dotnet.Test("--configuration", configuration, "-xml", $"{project}-testResults.xml", "-notrait", "category=failing")
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test", project))
.Environment(vsvars)
.EnvironmentVariable("PATH", $"{DotNetCli.Stage2.BinPath}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}")
.EnvironmentVariable("TEST_ARTIFACTS", Dirs.TestArtifacts)
.Execute();
if (result.ExitCode != 0)
{
failingTests.Add(project);
}
}
if (failingTests.Any())
{
foreach (var project in failingTests)
{
c.Error($"{project} failed");
}
return c.Failed("Tests failed!");
}
return c.Success();
}
[Target]
public static BuildTargetResult ValidateDependencies(BuildTargetContext c)
{
var configuration = c.BuildContext.Get<string>("Configuration");
var dotnet = DotNetCli.Stage2;
c.Info("Publishing MultiProjectValidator");
dotnet.Publish("--output", Path.Combine(Dirs.Output, "tools"), "--configuration", configuration)
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools", "MultiProjectValidator"))
.Execute()
.EnsureSuccessful();
var validator = Path.Combine(Dirs.Output, "tools", $"pjvalidate{Constants.ExeSuffix}");
Cmd(validator, Path.Combine(c.BuildContext.BuildDirectory, "src"))
.Execute();
return c.Success();
}
private static IEnumerable<string> GetTestProjects()
{
List<string> testProjects = new List<string>();
testProjects.AddRange(TestProjects);
if (CurrentPlatform.IsWindows)
{
testProjects.AddRange(WindowsTestProjects);
}
return testProjects;
}
private static BuildTargetResult BuildTestAssets(BuildTargetContext c, string testAssetsRoot, DotNetCli dotnet, string framework)
{
CleanBinObj(c, testAssetsRoot);
var nobuildFileName = ".noautobuild";
var projects = Directory.GetFiles(testAssetsRoot, "project.json", SearchOption.AllDirectories)
.Where(p => !ConditionalTestAssets.Where(s => !s.Skip() && p.EndsWith(Path.Combine(s.Path, "project.json"))).Any())
.Where(p => !File.Exists(Path.Combine(Path.GetDirectoryName(p), nobuildFileName)));
foreach (var project in projects)
{
c.Info($"Building: {project}");
dotnet.Build("--framework", framework)
.WorkingDirectory(Path.GetDirectoryName(project))
.Execute()
.EnsureSuccessful();
}
return c.Success();
}
private static Dictionary<string, string> LoadVsVars(BuildTargetContext c)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return new Dictionary<string, string>();
}
c.Verbose("Start Collecting Visual Studio Environment Variables");
var vsvarsPath = Path.GetFullPath(Path.Combine(Environment.GetEnvironmentVariable("VS140COMNTOOLS"), "..", "..", "VC"));
// Write a temp batch file because that seems to be the easiest way to do this (argument parsing is hard)
var temp = Path.Combine(Path.GetTempPath(), $"{Path.GetRandomFileName()}.cmd");
File.WriteAllText(temp, $@"@echo off
cd {vsvarsPath}
call vcvarsall.bat x64
set");
CommandResult result;
try
{
result = Cmd(Environment.GetEnvironmentVariable("COMSPEC"), "/c", temp)
.WorkingDirectory(vsvarsPath)
.CaptureStdOut()
.Execute();
}
finally
{
if (File.Exists(temp))
{
File.Delete(temp);
}
}
result.EnsureSuccessful();
var vars = new Dictionary<string, string>();
foreach (var line in result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
{
var splat = line.Split(new[] { '=' }, 2);
if (splat.Length == 2)
{
c.Verbose($"Adding variable '{line}'");
vars[splat[0]] = splat[1];
}
else
{
c.Info($"Skipping VS Env Variable. Unknown format: '{line}'");
}
}
c.Verbose("Finish Collecting Visual Studio Environment Variables");
return vars;
}
}
}

View file

@ -0,0 +1,81 @@
#
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
param(
[string]$Configuration="Debug",
[string]$Architecture="x64",
[string[]]$Targets=@("Default"),
[switch]$NoPackage,
[switch]$Help)
if($Help)
{
Write-Host "Usage: .\build.ps1 [-Configuration <CONFIGURATION>] [-NoPackage] [-Help] [-Targets <TARGETS...>]"
Write-Host ""
Write-Host "Options:"
Write-Host " -Configuration <CONFIGURATION> Build the specified Configuration (Debug or Release, default: Debug)"
Write-Host " -Architecture <ARCHITECTURE> Build the specified architecture (x64 or x86 (supported only on Windows), default: x64)"
Write-Host " -Targets <TARGETS...> Comma separated build targets to run (Init, Compile, Publish, etc.; Default is a full build and publish)"
Write-Host " -NoPackage Skip packaging targets"
Write-Host " -Help Display this help message"
exit 0
}
$env:CONFIGURATION = $Configuration;
$RepoRoot = "$PSScriptRoot\..\.."
if($NoPackage)
{
$env:DOTNET_BUILD_SKIP_PACKAGING=1
}
else
{
$env:DOTNET_BUILD_SKIP_PACKAGING=0
}
# Load Branch Info
cat "$RepoRoot\branchinfo.txt" | ForEach-Object {
if(!$_.StartsWith("#") -and ![String]::IsNullOrWhiteSpace($_)) {
$splat = $_.Split([char[]]@("="), 2)
Set-Content "env:\$($splat[0])" -Value $splat[1]
}
}
# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
if (!$env:DOTNET_INSTALL_DIR)
{
$env:DOTNET_INSTALL_DIR="$RepoRoot\.dotnet_stage0\Windows\$Architecture"
}
if (!(Test-Path $env:DOTNET_INSTALL_DIR))
{
mkdir $env:DOTNET_INSTALL_DIR | Out-Null
}
# Install a stage 0
Write-Host "Installing .NET Core CLI Stage 0 from branchinfo channel"
& "$RepoRoot\scripts\obtain\dotnet-install.ps1" -Channel $env:CHANNEL -Architecture $Architecture -Verbose
if($LASTEXITCODE -ne 0) { throw "Failed to install stage0" }
# Put the stage0 on the path
$env:PATH = "$env:DOTNET_INSTALL_DIR;$env:PATH"
# Restore the build scripts
Write-Host "Restoring Build Script projects..."
pushd "$PSScriptRoot\.."
dotnet restore --infer-runtimes
if($LASTEXITCODE -ne 0) { throw "Failed to restore" }
popd
# Publish the builder
Write-Host "Compiling Build Scripts..."
dotnet publish "$PSScriptRoot" -o "$PSScriptRoot\bin" --framework netcoreapp1.0
if($LASTEXITCODE -ne 0) { throw "Failed to compile build scripts" }
# Run the builder
Write-Host "Invoking Build Scripts..."
Write-Host " Configuration: $env:CONFIGURATION"
& "$PSScriptRoot\bin\dotnet-cli-build.exe" @Targets
if($LASTEXITCODE -ne 0) { throw "Build failed" }

View file

@ -0,0 +1,118 @@
#!/usr/bin/env bash
#
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
set -e
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
OLDPATH="$PATH"
REPOROOT="$DIR/../.."
source "$REPOROOT/scripts/common/_prettyprint.sh"
while [[ $# > 0 ]]; do
lowerI="$(echo $1 | awk '{print tolower($0)}')"
case $lowerI in
-c|--configuration)
export CONFIGURATION=$2
shift
;;
--targets)
IFS=',' read -r -a targets <<< $2
shift
;;
--nopackage)
export DOTNET_BUILD_SKIP_PACKAGING=1
;;
--skip-prereqs)
# Allow CI to disable prereqs check since the CI has the pre-reqs but not ldconfig it seems
export DOTNET_INSTALL_SKIP_PREREQS=1
;;
--help)
echo "Usage: $0 [--configuration <CONFIGURATION>] [--skip-prereqs] [--nopackage] [--docker <IMAGENAME>] [--help] [--targets <TARGETS...>]"
echo ""
echo "Options:"
echo " --configuration <CONFIGURATION> Build the specified Configuration (Debug or Release, default: Debug)"
echo " --targets <TARGETS...> Comma separated build targets to run (Init, Compile, Publish, etc.; Default is a full build and publish)"
echo " --nopackage Skip packaging targets"
echo " --skip-prereqs Skip checks for pre-reqs in dotnet_install"
echo " --docker <IMAGENAME> Build in Docker using the Dockerfile located in scripts/docker/IMAGENAME"
echo " --help Display this help message"
echo " <TARGETS...> The build targets to run (Init, Compile, Publish, etc.; Default is a full build and publish)"
exit 0
;;
*)
break
;;
esac
shift
done
# Set up the environment to be used for building with clang.
if which "clang-3.5" > /dev/null 2>&1; then
export CC="$(which clang-3.5)"
export CXX="$(which clang++-3.5)"
elif which "clang-3.6" > /dev/null 2>&1; then
export CC="$(which clang-3.6)"
export CXX="$(which clang++-3.6)"
elif which clang > /dev/null 2>&1; then
export CC="$(which clang)"
export CXX="$(which clang++)"
else
error "Unable to find Clang Compiler"
error "Install clang-3.5 or clang3.6"
exit 1
fi
# Load Branch Info
while read line; do
if [[ $line != \#* ]]; then
IFS='=' read -ra splat <<< "$line"
export ${splat[0]}="${splat[1]}"
fi
done < "$REPOROOT/branchinfo.txt"
# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
[ -z "$DOTNET_INSTALL_DIR" ] && export DOTNET_INSTALL_DIR=$REPOROOT/.dotnet_stage0/$(uname)
[ -d "$DOTNET_INSTALL_DIR" ] || mkdir -p $DOTNET_INSTALL_DIR
$REPOROOT/scripts/obtain/dotnet-install.sh --channel $CHANNEL --verbose
# Put stage 0 on the PATH (for this shell only)
PATH="$DOTNET_INSTALL_DIR:$PATH"
# Increases the file descriptors limit for this bash. It prevents an issue we were hitting during restore
FILE_DESCRIPTOR_LIMIT=$( ulimit -n )
if [ $FILE_DESCRIPTOR_LIMIT -lt 1024 ]
then
echo "Increasing file description limit to 1024"
ulimit -n 1024
fi
# Restore the build scripts
echo "Restoring Build Script projects..."
(
cd "$DIR/.."
dotnet restore --infer-runtimes
)
# Build the builder
echo "Compiling Build Scripts..."
dotnet publish "$DIR" -o "$DIR/bin" --framework netcoreapp1.0
export PATH="$OLDPATH"
# Run the builder
echo "Invoking Build Scripts..."
echo "Configuration: $CONFIGURATION"
$DIR/bin/dotnet-cli-build ${targets[@]}
exit $?

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>d7b9695d-23eb-4ea8-b8ab-707a0092e1d5</ProjectGuid>
<RootNamespace>Microsoft.DotNet.Cli.Build</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,27 @@
{
"version": "1.0.0-*",
"description": "Build scripts for dotnet-cli",
"compilationOptions": {
"emitEntryPoint": true
},
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027",
"Microsoft.CSharp": "4.0.1-rc2-24027",
"System.Dynamic.Runtime": "4.0.11-rc2-24027",
"System.Reflection.Metadata": "1.3.0-rc2-24027",
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-24027",
"System.Xml.XmlSerializer": "4.0.11-rc2-24027",
"WindowsAzure.Storage": "6.2.2-preview",
"Microsoft.DotNet.Cli.Build.Framework": {"target":"project"},
"shared-build-targets-utils": {"target": "project"}
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
}
}