diff --git a/source/Cosmos.Build.Builder/CosmosTask.cs b/source/Cosmos.Build.Builder/CosmosTask.cs index 13a649a7c..5ef21ebf5 100644 --- a/source/Cosmos.Build.Builder/CosmosTask.cs +++ b/source/Cosmos.Build.Builder/CosmosTask.cs @@ -1,431 +1,459 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using Microsoft.Win32; -using NuGet.Configuration; - -using Cosmos.Build.Installer; - -namespace Cosmos.Build.Builder { - /// - /// Cosmos task. - /// - /// - public class CosmosTask : Task { - private string mCosmosPath; // Root Cosmos dir - private string mVsipPath; // Build/VSIP - private string mAppDataPath; // User Kit in AppData - private string mSourcePath; // Cosmos source rood - private string mInnoPath; - private string mInnoFile; - - private BuildState mBuildState; - private int mReleaseNo; - private List mExceptionList = new List(); - - public CosmosTask(string aCosmosDir, int aReleaseNo) { - mCosmosPath = aCosmosDir; - mVsipPath = Path.Combine(mCosmosPath, @"Build\VSIP"); - mSourcePath = Path.Combine(mCosmosPath, "source"); - mAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Cosmos User Kit"); - - mReleaseNo = aReleaseNo; - mInnoFile = Path.Combine(mCosmosPath, @"Setup\Cosmos.iss"); - } - - /// - /// Get name of the setup file based on release number and the current setting. - /// - /// Release number for the current setup. - /// Name of the setup file. - public static string GetSetupName(int releaseNumber) { - string setupName = $"CosmosUserKit-{releaseNumber}-vs2017"; - - if (App.UseVsHive) { - setupName += "Exp"; - } - - return setupName; - } - - private void CleanDirectory(string aName, string aPath) { - if (Directory.Exists(aPath)) { - Log.WriteLine("Cleaning up existing " + aName + " directory."); - Directory.Delete(aPath, true); - } - - Log.WriteLine("Creating " + aName + " as " + aPath); - Directory.CreateDirectory(aPath); - } - - protected override List DoRun() { - if (PrereqsOK()) { - Section("Init Directories"); - CleanDirectory("VSIP", mVsipPath); - if (!App.IsUserKit) { - CleanDirectory("User Kit", mAppDataPath); - } - - CompileCosmos(); - CreateSetup(); - - if (!App.IsUserKit) { - RunSetup(); - WriteDevKit(); - if (!App.DoNotLaunchVS) { - LaunchVS(); - } - } - Done(); - } - - return mExceptionList; - } - - protected void MSBuild(string aSlnFile, string aBuildCfg) { - string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); - string xParams = $"{Quoted(aSlnFile)} " + - "/nologo " + - "/maxcpucount " + - "/nodeReuse:False " + - "/p:DeployExtension=False " + - $"/p:Configuration={Quoted(aBuildCfg)} " + - $"/p:Platform={Quoted("Any CPU")} " + - $"/p:OutputPath={Quoted(mVsipPath)}"; - - if (!App.NoMSBuildClean) { - StartConsole(xMSBuild, $"/t:Clean {xParams}"); - } - StartConsole(xMSBuild, $"/t:Build {xParams}"); - } - - protected int NumProcessesContainingName(string name) { - return (from x in Process.GetProcesses() where x.ProcessName.Contains(name) select x).Count(); - } - - protected void CheckIfBuilderRunning() { - //Check for builder process - Log.WriteLine("Check if Builder is running."); - // Check > 1 so we exclude ourself. - if (NumProcessesContainingName("Cosmos.Build.Builder") > 1) { - throw new Exception("Another instance of builder is running."); - } - } - - protected void CheckIfUserKitRunning() { - Log.WriteLine("Check if User Kit Installer is already running."); - if (NumProcessesContainingName("CosmosUserKit") > 0) { - throw new Exception("Another instance of the user kit installer is running."); - } - } - - protected void CheckIfVSandCoRunning() { - bool xRunningFound = false; - if (IsRunning("devenv")) { - xRunningFound = true; - Log.WriteLine("--Visual Studio is running."); - } - if (IsRunning("VSIXInstaller")) { +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Microsoft.Win32; +using NuGet.Configuration; + +using Cosmos.Build.Installer; + +namespace Cosmos.Build.Builder { + /// + /// Cosmos task. + /// + /// + public class CosmosTask : Task { + private string mCosmosPath; // Root Cosmos dir + private string mVsipPath; // Build/VSIP + private string mAppDataPath; // User Kit in AppData + private string mSourcePath; // Cosmos source rood + private string mInnoPath; + private string mInnoFile; + private string mIL2CPUPath; + private string mXSPath; + + private BuildState mBuildState; + private int mReleaseNo; + private List mExceptionList = new List(); + + public CosmosTask(string aCosmosDir, int aReleaseNo) { + mCosmosPath = aCosmosDir; + mVsipPath = Path.Combine(mCosmosPath, @"Build\VSIP"); + mSourcePath = Path.Combine(mCosmosPath, "source"); + mAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Cosmos User Kit"); + + mReleaseNo = aReleaseNo; + mInnoFile = Path.Combine(mCosmosPath, @"Setup\Cosmos.iss"); + mXSPath = Path.GetFullPath(Path.Combine(mCosmosPath, @"..\XSharp")); + mIL2CPUPath = Path.GetFullPath(Path.Combine(mCosmosPath, @"..\IL2CPU")); + } + + /// + /// Get name of the setup file based on release number and the current setting. + /// + /// Release number for the current setup. + /// Name of the setup file. + public static string GetSetupName(int releaseNumber) { + string setupName = $"CosmosUserKit-{releaseNumber}-vs2017"; + + if (App.UseVsHive) { + setupName += "Exp"; + } + + return setupName; + } + + private void CleanDirectory(string aName, string aPath) { + if (Directory.Exists(aPath)) { + Log.WriteLine("Cleaning up existing " + aName + " directory."); + Directory.Delete(aPath, true); + } + + Log.WriteLine("Creating " + aName + " as " + aPath); + Directory.CreateDirectory(aPath); + } + + protected override List DoRun() { + if (PrereqsOK()) { + Section("Init Directories"); + CleanDirectory("VSIP", mVsipPath); + if (!App.IsUserKit) { + CleanDirectory("User Kit", mAppDataPath); + } + + CompileCosmos(); + CreateSetup(); + + if (!App.IsUserKit) { + RunSetup(); + WriteDevKit(); + if (!App.DoNotLaunchVS) { + LaunchVS(); + } + } + Done(); + } + + return mExceptionList; + } + + protected void MSBuild(string aSlnFile, string aBuildCfg) { + string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); + string xParams = $"{Quoted(aSlnFile)} " + + "/nologo " + + "/maxcpucount " + + "/nodeReuse:False " + + "/p:DeployExtension=False " + + $"/p:Configuration={Quoted(aBuildCfg)} " + + $"/p:Platform={Quoted("Any CPU")} " + + $"/p:OutputPath={Quoted(mVsipPath)}"; + + if (!App.NoMSBuildClean) { + StartConsole(xMSBuild, $"/t:Clean {xParams}"); + } + StartConsole(xMSBuild, $"/t:Build {xParams}"); + } + + protected int NumProcessesContainingName(string name) { + return (from x in Process.GetProcesses() where x.ProcessName.Contains(name) select x).Count(); + } + + protected void CheckIfBuilderRunning() { + //Check for builder process + Log.WriteLine("Check if Builder is running."); + // Check > 1 so we exclude ourself. + if (NumProcessesContainingName("Cosmos.Build.Builder") > 1) { + throw new Exception("Another instance of builder is running."); + } + } + + protected void CheckIfUserKitRunning() { + Log.WriteLine("Check if User Kit Installer is already running."); + if (NumProcessesContainingName("CosmosUserKit") > 0) { + throw new Exception("Another instance of the user kit installer is running."); + } + } + + protected void CheckIfVSandCoRunning() { + bool xRunningFound = false; + if (IsRunning("devenv")) { + xRunningFound = true; + Log.WriteLine("--Visual Studio is running."); + } + if (IsRunning("VSIXInstaller")) { xRunningFound = true; Log.WriteLine("--VSIXInstaller is running."); - } - if (IsRunning("ServiceHub.IdentityHost")) { + } + if (IsRunning("ServiceHub.IdentityHost")) { xRunningFound = true; Log.WriteLine("--ServiceHub.IdentityHost is running."); - } - if (IsRunning("ServiceHub.VSDetouredHost")) { + } + if (IsRunning("ServiceHub.VSDetouredHost")) { xRunningFound = true; Log.WriteLine("--ServiceHub.VSDetouredHost is running."); - } - if (IsRunning("ServiceHub.Host.Node.x86")) { + } + if (IsRunning("ServiceHub.Host.Node.x86")) { xRunningFound = true; Log.WriteLine("--ServiceHub.Host.Node.x86 is running."); - } - if (IsRunning("ServiceHub.SettingsHost")) { + } + if (IsRunning("ServiceHub.SettingsHost")) { xRunningFound = true; Log.WriteLine("--ServiceHub.SettingsHost is running."); - } - if (IsRunning("ServiceHub.Host.CLR.x86")) { + } + if (IsRunning("ServiceHub.Host.CLR.x86")) { xRunningFound = true; Log.WriteLine("--ServiceHub.Host.CLR.x86 is running."); - } + } if (xRunningFound) { Log.WriteLine("--Running blockers found. Setup will warning you and wait for it."); - } - } - - protected void NotFound(string aName) { - mExceptionList.Add("Prerequisite '" + aName + "' not found."); - mBuildState = BuildState.PrerequisiteMissing; - } - - protected bool PrereqsOK() { - Section("Check Prerequisites"); - - CheckIfUserKitRunning(); - CheckIfVSandCoRunning(); - CheckIfBuilderRunning(); - - CheckForNetCore(); - CheckForVisualStudioExtensionTools(); - CheckForInno(); - - return mBuildState != BuildState.PrerequisiteMissing; - } - - private void CheckForInno() { - Log.WriteLine("Check for Inno Setup"); - using (var xKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 5_is1", false)) { - if (xKey == null) { - mExceptionList.Add("Cannot find Inno Setup."); - mBuildState = BuildState.PrerequisiteMissing; - return; - } - mInnoPath = (string)xKey.GetValue("InstallLocation"); - if (string.IsNullOrWhiteSpace(mInnoPath)) { - mExceptionList.Add("Cannot find Inno Setup."); - mBuildState = BuildState.PrerequisiteMissing; - return; - } - } - - Log.WriteLine("Check for Inno Preprocessor"); - if (!File.Exists(Path.Combine(mInnoPath, "ISPP.dll"))) { - mExceptionList.Add("Inno Preprocessor not detected."); - mBuildState = BuildState.PrerequisiteMissing; - return; - } - } - - private void CheckForNetCore() { - Log.WriteLine("Check for .NET Core"); - - if (!Paths.VSInstancePackages.Contains("Microsoft.VisualStudio.Workload.NetCoreTools")) { - mExceptionList.Add(".NET Core not detected."); - mBuildState = BuildState.PrerequisiteMissing; - } - } - - private void CheckForVisualStudioExtensionTools() { - Log.WriteLine("Check for Visual Studio Extension Tools"); - - if (!Paths.VSInstancePackages.Contains("Microsoft.VisualStudio.Workload.VisualStudioExtension")) { - mExceptionList.Add("Visual Studio Extension tools not detected."); - mBuildState = BuildState.PrerequisiteMissing; - } - } - - private void WriteDevKit() { - Section("Write Dev Kit to Registry"); - - // Inno deletes this from registry, so we must add this after. - // We let Inno delete it, so if user runs it by itself they get - // only UserKit, and no DevKit settings. - // HKCU instead of HKLM because builder does not run as admin. - // - // HKCU is not redirected. - using (var xKey = Registry.CurrentUser.CreateSubKey(@"Software\Cosmos")) { - xKey.SetValue("DevKit", mCosmosPath); - } - } - - private void Clean(string project) - { - string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); - string xListParams = $"sources List"; - StartConsole(xNuget, xListParams); - - var xStart = new ProcessStartInfo(); - xStart.FileName = xNuget; - xStart.WorkingDirectory = CurrPath; - xStart.Arguments = xListParams; - xStart.UseShellExecute = false; - xStart.CreateNoWindow = true; - xStart.RedirectStandardOutput = true; - xStart.RedirectStandardError = true; - using (var xProcess = Process.Start(xStart)) - { - using (var xReader = xProcess.StandardOutput) - { - string xLine; - while (true) - { - xLine = xReader.ReadLine(); - if (xLine == null) - { - break; - } - if (xLine.Contains("Cosmos Local Package Feed")) - { - string xUninstallParams = $"sources Remove -Name \"Cosmos Local Package Feed\""; - StartConsole(xNuget, xUninstallParams); - } - } - } - } - - // Clean Cosmos packages from NuGet cache - var xGlobalFolder = SettingsUtility.GetGlobalPackagesFolder(Settings.LoadDefaultSettings(Environment.SystemDirectory)); - - // Later we should specify the packages, currently we're moving to gen3 so package names are a bit unstable - foreach (var xFolder in Directory.EnumerateDirectories(xGlobalFolder)) - { - if (new DirectoryInfo(xFolder).Name.StartsWith("Cosmos", StringComparison.InvariantCultureIgnoreCase)) - { - CleanPackage(xFolder); - } - } - - void CleanPackage(string aPackage) - { - var xPath = Path.Combine(xGlobalFolder, aPackage); - - if (Directory.Exists(xPath)) - { - Directory.Delete(xPath, true); - } - } - } - - private void Restore(string project) - { - string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); - string xRestoreParams = $"restore {Quoted(project)}"; - StartConsole(xNuget, xRestoreParams); - } - - private void Update() { - string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); - string xUpdateParams = $"update -self"; - StartConsole(xNuget, xUpdateParams); - } - - private void Pack(string project, string destDir) { - string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); - string xParams = $"{Quoted(project)} /nodeReuse:False /t:Restore;Pack /maxcpucount /p:PackageOutputPath={Quoted(destDir)}"; - StartConsole(xMSBuild, xParams); - } - - private void Publish(string project, string destDir) { - string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); - string xParams = $"{Quoted(project)} /nodeReuse:False /t:Publish /maxcpucount /p:RuntimeIdentifier=win7-x86 /p:PublishDir={Quoted(destDir)}"; - StartConsole(xMSBuild, xParams); - } - - private void CompileCosmos() { - string xVsipDir = Path.Combine(mCosmosPath, "Build", "VSIP"); - string xNugetPkgDir = Path.Combine(xVsipDir, "Packages"); - - Section("Clean NuGet Local Feed"); - Clean(Path.Combine(mCosmosPath, @"Build.sln")); - - Section("Restore NuGet Packages"); - Restore(Path.Combine(mCosmosPath, @"Build.sln")); - Restore(Path.Combine(mCosmosPath, @"../IL2CPU/IL2CPU.sln")); - Restore(Path.Combine(mCosmosPath, @"../XSharp/XSharp.sln")); - - Section("Update NuGet"); - Update(); - - Section("Build Cosmos"); - // Build.sln is the old master but because of how VS manages refs, we have to hack - // this short term with the new slns. - MSBuild(Path.Combine(mCosmosPath, @"Build.sln"), "Debug"); - - Section("Publish Tools"); - //Publish(Path.Combine(mSourcePath, "Cosmos.Build.MSBuild"), Path.Combine(xVsipDir, "MSBuild")); - Publish(Path.Combine(mSourcePath, "../../IL2CPU/source/IL2CPU"), Path.Combine(xVsipDir, "IL2CPU")); - Publish(Path.Combine(mCosmosPath, "Tools", "NASM"), Path.Combine(xVsipDir, "NASM")); - - Section("Create Packages"); - // - Pack(Path.Combine(mSourcePath, "Cosmos.Build.Tasks"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "Cosmos.Common"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "Cosmos.Core"), xNugetPkgDir); - Pack(Path.Combine(mSourcePath, "Cosmos.Core_Plugs"), xNugetPkgDir); - Pack(Path.Combine(mSourcePath, "Cosmos.Core_Asm"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "Cosmos.HAL2"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "Cosmos.System2"), xNugetPkgDir); - Pack(Path.Combine(mSourcePath, "Cosmos.System2_Plugs"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "Cosmos.Debug.Kernel"), xNugetPkgDir); - Pack(Path.Combine(mSourcePath, "Cosmos.Debug.Kernel.Plugs.Asm"), xNugetPkgDir); - // - Pack(Path.Combine(mSourcePath, "../../IL2CPU/source/IL2CPU.API"), xNugetPkgDir); - } - - private void CopyTemplates() { - Section("Copy Templates"); - - using (var x = new FileMgr(Path.Combine(mSourcePath, @"Cosmos.VS.Package\obj\Debug"), mVsipPath)) { - x.Copy("CosmosProject (C#).zip"); - x.Copy("CosmosKernel (C#).zip"); - x.Copy("CosmosProject (F#).zip"); - x.Copy("Cosmos.zip"); - x.Copy("CosmosProject (VB).zip"); - x.Copy("CosmosKernel (VB).zip"); - x.Copy(mSourcePath + @"XSharp.VS\Template\XSharpFileItem.zip"); - } - } - - private void CreateSetup() { - Section("Creating Setup"); - - string xISCC = Path.Combine(mInnoPath, "ISCC.exe"); - if (!File.Exists(xISCC)) { - mExceptionList.Add("Cannot find Inno setup."); - return; - } - - string xCfg = App.IsUserKit ? "UserKit" : "DevKit"; - string vsVersionConfiguration = "vs2017"; - - // Use configuration which will install to the VS Exp Hive - if (App.UseVsHive) { - vsVersionConfiguration += "Exp"; - } - Log.WriteLine($" {xISCC} /Q {Quoted(mInnoFile)} /dBuildConfiguration={xCfg} /dVSVersion={vsVersionConfiguration} /dChangeSetVersion={Quoted(mReleaseNo.ToString())}"); - StartConsole(xISCC, $"/Q {Quoted(mInnoFile)} /dBuildConfiguration={xCfg} /dVSVersion={vsVersionConfiguration} /dChangeSetVersion={Quoted(mReleaseNo.ToString())}"); - } - - private void LaunchVS() { - Section("Launching Visual Studio"); - - string xVisualStudio = Path.Combine(Paths.VSPath, "Common7", "IDE", "devenv.exe"); - if (!File.Exists(xVisualStudio)) { - mExceptionList.Add("Cannot find Visual Studio."); - return; - } - - if (App.ResetHive) { - Log.WriteLine("Resetting hive"); - Start(xVisualStudio, @"/setup /rootsuffix Exp /ranu"); - } - - Log.WriteLine("Launching Visual Studio"); - Start(xVisualStudio, Quoted(mCosmosPath + @"Kernel.sln"), false, true); - } - - private void RunSetup() { - Section("Running Setup"); - - // These cache in RAM which cause problems, so we kill them if present. - KillProcesses("dotnet"); - KillProcesses("msbuild"); - - string setupName = GetSetupName(mReleaseNo); - - Start(mCosmosPath + @"Setup\Output\" + setupName + ".exe", @"/SILENT"); - } - - private void Done() { - Section("Build Complete!"); - } - } -} + } + } + + protected void NotFound(string aName) { + mExceptionList.Add("Prerequisite '" + aName + "' not found."); + mBuildState = BuildState.PrerequisiteMissing; + } + + protected bool PrereqsOK() { + Section("Check Prerequisites"); + + CheckIfUserKitRunning(); + CheckIfVSandCoRunning(); + CheckIfBuilderRunning(); + + CheckForNetCore(); + CheckForVisualStudioExtensionTools(); + CheckForInno(); + CheckForRepos(); + + return mBuildState != BuildState.PrerequisiteMissing; + } + + private void CheckForRepos() + { + Log.WriteLine("Checking for existing IL2CPU and XSharp repositories..."); + if (!Directory.Exists(mIL2CPUPath)) + { + if (!File.Exists(Path.Combine(mIL2CPUPath, @"IL2CPU.sln"))) + { + mExceptionList.Add("Missing IL2CPU Repository! Make sure to clone IL2CPU in the parent directory of Cosmos! Download IL2CPU and extract to " + mIL2CPUPath + "."); + mBuildState = BuildState.PrerequisiteMissing; + return; + } + } + else if (!Directory.Exists(mXSPath)) + { + if (!File.Exists(Path.Combine(mXSPath, @"XSharp.sln"))) + { + mExceptionList.Add("Missing XSharp Repository! Make sure to clone XSharp in the parent directory of Cosmos! Download XSharp and extract to " + mXSPath + "."); + mBuildState = BuildState.PrerequisiteMissing; + return; + } + } + } + + private void CheckForInno() { + Log.WriteLine("Check for Inno Setup"); + using (var xKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 5_is1", false)) { + if (xKey == null) { + mExceptionList.Add("Cannot find Inno Setup."); + mBuildState = BuildState.PrerequisiteMissing; + return; + } + mInnoPath = (string)xKey.GetValue("InstallLocation"); + if (string.IsNullOrWhiteSpace(mInnoPath)) { + mExceptionList.Add("Cannot find Inno Setup."); + mBuildState = BuildState.PrerequisiteMissing; + return; + } + } + + Log.WriteLine("Check for Inno Preprocessor"); + if (!File.Exists(Path.Combine(mInnoPath, "ISPP.dll"))) { + mExceptionList.Add("Inno Preprocessor not detected."); + mBuildState = BuildState.PrerequisiteMissing; + return; + } + } + + private void CheckForNetCore() { + Log.WriteLine("Check for .NET Core"); + + if (!Paths.VSInstancePackages.Contains("Microsoft.VisualStudio.Workload.NetCoreTools")) { + mExceptionList.Add(".NET Core not detected."); + mBuildState = BuildState.PrerequisiteMissing; + } + } + + private void CheckForVisualStudioExtensionTools() { + Log.WriteLine("Check for Visual Studio Extension Tools"); + + if (!Paths.VSInstancePackages.Contains("Microsoft.VisualStudio.Workload.VisualStudioExtension")) { + mExceptionList.Add("Visual Studio Extension tools not detected."); + mBuildState = BuildState.PrerequisiteMissing; + } + } + + private void WriteDevKit() { + Section("Write Dev Kit to Registry"); + + // Inno deletes this from registry, so we must add this after. + // We let Inno delete it, so if user runs it by itself they get + // only UserKit, and no DevKit settings. + // HKCU instead of HKLM because builder does not run as admin. + // + // HKCU is not redirected. + using (var xKey = Registry.CurrentUser.CreateSubKey(@"Software\Cosmos")) { + xKey.SetValue("DevKit", mCosmosPath); + } + } + + private void Clean(string project) + { + string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); + string xListParams = $"sources List"; + StartConsole(xNuget, xListParams); + + var xStart = new ProcessStartInfo(); + xStart.FileName = xNuget; + xStart.WorkingDirectory = CurrPath; + xStart.Arguments = xListParams; + xStart.UseShellExecute = false; + xStart.CreateNoWindow = true; + xStart.RedirectStandardOutput = true; + xStart.RedirectStandardError = true; + using (var xProcess = Process.Start(xStart)) + { + using (var xReader = xProcess.StandardOutput) + { + string xLine; + while (true) + { + xLine = xReader.ReadLine(); + if (xLine == null) + { + break; + } + if (xLine.Contains("Cosmos Local Package Feed")) + { + string xUninstallParams = $"sources Remove -Name \"Cosmos Local Package Feed\""; + StartConsole(xNuget, xUninstallParams); + } + } + } + } + + // Clean Cosmos packages from NuGet cache + var xGlobalFolder = SettingsUtility.GetGlobalPackagesFolder(Settings.LoadDefaultSettings(Environment.SystemDirectory)); + + // Later we should specify the packages, currently we're moving to gen3 so package names are a bit unstable + foreach (var xFolder in Directory.EnumerateDirectories(xGlobalFolder)) + { + if (new DirectoryInfo(xFolder).Name.StartsWith("Cosmos", StringComparison.InvariantCultureIgnoreCase)) + { + CleanPackage(xFolder); + } + } + + void CleanPackage(string aPackage) + { + var xPath = Path.Combine(xGlobalFolder, aPackage); + + if (Directory.Exists(xPath)) + { + Directory.Delete(xPath, true); + } + } + } + + private void Restore(string project) + { + string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); + string xRestoreParams = $"restore {Quoted(project)}"; + StartConsole(xNuget, xRestoreParams); + } + + private void Update() { + string xNuget = Path.Combine(mCosmosPath, "Build", "Tools", "nuget.exe"); + string xUpdateParams = $"update -self"; + StartConsole(xNuget, xUpdateParams); + } + + private void Pack(string project, string destDir) { + string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); + string xParams = $"{Quoted(project)} /nodeReuse:False /t:Restore;Pack /maxcpucount /p:PackageOutputPath={Quoted(destDir)}"; + StartConsole(xMSBuild, xParams); + } + + private void Publish(string project, string destDir) { + string xMSBuild = Path.Combine(Paths.VSPath, "MSBuild", "15.0", "Bin", "msbuild.exe"); + string xParams = $"{Quoted(project)} /nodeReuse:False /t:Publish /maxcpucount /p:RuntimeIdentifier=win7-x86 /p:PublishDir={Quoted(destDir)}"; + StartConsole(xMSBuild, xParams); + } + + private void CompileCosmos() { + string xVsipDir = Path.Combine(mCosmosPath, "Build", "VSIP"); + string xNugetPkgDir = Path.Combine(xVsipDir, "Packages"); + + Section("Clean NuGet Local Feed"); + Clean(Path.Combine(mCosmosPath, @"Build.sln")); + + Section("Restore NuGet Packages"); + Restore(Path.Combine(mCosmosPath, @"Build.sln")); + Restore(Path.Combine(mCosmosPath, @"../IL2CPU/IL2CPU.sln")); + Restore(Path.Combine(mCosmosPath, @"../XSharp/XSharp.sln")); + + Section("Update NuGet"); + Update(); + + Section("Build Cosmos"); + // Build.sln is the old master but because of how VS manages refs, we have to hack + // this short term with the new slns. + MSBuild(Path.Combine(mCosmosPath, @"Build.sln"), "Debug"); + + Section("Publish Tools"); + //Publish(Path.Combine(mSourcePath, "Cosmos.Build.MSBuild"), Path.Combine(xVsipDir, "MSBuild")); + Publish(Path.Combine(mSourcePath, "../../IL2CPU/source/IL2CPU"), Path.Combine(xVsipDir, "IL2CPU")); + Publish(Path.Combine(mCosmosPath, "Tools", "NASM"), Path.Combine(xVsipDir, "NASM")); + + Section("Create Packages"); + // + Pack(Path.Combine(mSourcePath, "Cosmos.Build.Tasks"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "Cosmos.Common"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "Cosmos.Core"), xNugetPkgDir); + Pack(Path.Combine(mSourcePath, "Cosmos.Core_Plugs"), xNugetPkgDir); + Pack(Path.Combine(mSourcePath, "Cosmos.Core_Asm"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "Cosmos.HAL2"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "Cosmos.System2"), xNugetPkgDir); + Pack(Path.Combine(mSourcePath, "Cosmos.System2_Plugs"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "Cosmos.Debug.Kernel"), xNugetPkgDir); + Pack(Path.Combine(mSourcePath, "Cosmos.Debug.Kernel.Plugs.Asm"), xNugetPkgDir); + // + Pack(Path.Combine(mSourcePath, "../../IL2CPU/source/IL2CPU.API"), xNugetPkgDir); + } + + private void CopyTemplates() { + Section("Copy Templates"); + + using (var x = new FileMgr(Path.Combine(mSourcePath, @"Cosmos.VS.Package\obj\Debug"), mVsipPath)) { + x.Copy("CosmosProject (C#).zip"); + x.Copy("CosmosKernel (C#).zip"); + x.Copy("CosmosProject (F#).zip"); + x.Copy("Cosmos.zip"); + x.Copy("CosmosProject (VB).zip"); + x.Copy("CosmosKernel (VB).zip"); + x.Copy(mSourcePath + @"XSharp.VS\Template\XSharpFileItem.zip"); + } + } + + private void CreateSetup() { + Section("Creating Setup"); + + string xISCC = Path.Combine(mInnoPath, "ISCC.exe"); + if (!File.Exists(xISCC)) { + mExceptionList.Add("Cannot find Inno setup."); + return; + } + + string xCfg = App.IsUserKit ? "UserKit" : "DevKit"; + string vsVersionConfiguration = "vs2017"; + + // Use configuration which will install to the VS Exp Hive + if (App.UseVsHive) { + vsVersionConfiguration += "Exp"; + } + Log.WriteLine($" {xISCC} /Q {Quoted(mInnoFile)} /dBuildConfiguration={xCfg} /dVSVersion={vsVersionConfiguration} /dChangeSetVersion={Quoted(mReleaseNo.ToString())}"); + StartConsole(xISCC, $"/Q {Quoted(mInnoFile)} /dBuildConfiguration={xCfg} /dVSVersion={vsVersionConfiguration} /dChangeSetVersion={Quoted(mReleaseNo.ToString())}"); + } + + private void LaunchVS() { + Section("Launching Visual Studio"); + + string xVisualStudio = Path.Combine(Paths.VSPath, "Common7", "IDE", "devenv.exe"); + if (!File.Exists(xVisualStudio)) { + mExceptionList.Add("Cannot find Visual Studio."); + return; + } + + if (App.ResetHive) { + Log.WriteLine("Resetting hive"); + Start(xVisualStudio, @"/setup /rootsuffix Exp /ranu"); + } + + Log.WriteLine("Launching Visual Studio"); + Start(xVisualStudio, Quoted(mCosmosPath + @"Kernel.sln"), false, true); + } + + private void RunSetup() { + Section("Running Setup"); + + // These cache in RAM which cause problems, so we kill them if present. + KillProcesses("dotnet"); + KillProcesses("msbuild"); + + string setupName = GetSetupName(mReleaseNo); + + Start(mCosmosPath + @"Setup\Output\" + setupName + ".exe", @"/SILENT"); + } + + private void Done() { + Section("Build Complete!"); + } + } +}