Add support for building Windows x86 version of dotnet CLI

- Changes to build scripts to produce Winx86 build artifacts like
  zip/installer.
- Change to run Nuget-xplat in the same process as dotnet.exe instead of
  spinning up a new 'corerun' process.
This commit is contained in:
Sridhar Periyasamy 2016-02-23 18:04:49 -08:00
parent 2aedd677c6
commit 834edfbc9c
11 changed files with 89 additions and 44 deletions

View file

@ -71,7 +71,7 @@ function RunCandle
-dBuildVersion="$env:DOTNET_MSI_VERSION" `
-dDisplayVersion="$env:DOTNET_CLI_VERSION" `
-dReleaseSuffix="$env:ReleaseSuffix" `
-arch x64 `
-arch "$env:ARCHITECTURE" `
-ext WixDependencyExtension.dll `
"$AuthWsxRoot\dotnet.wxs" `
"$AuthWsxRoot\provider.wxs" `
@ -136,7 +136,7 @@ function RunCandleForBundle
-dDisplayVersion="$env:DOTNET_CLI_VERSION" `
-dReleaseSuffix="$env:ReleaseSuffix" `
-dMsiSourcePath="$DotnetMSIOutput" `
-arch x64 `
-arch "$env:ARCHITECTURE" `
-ext WixBalExtension.dll `
-ext WixUtilExtension.dll `
-ext WixTagExtension.dll `
@ -190,8 +190,8 @@ if(!(Test-Path $PackageDir))
mkdir $PackageDir | Out-Null
}
$DotnetMSIOutput = Join-Path $PackageDir "dotnet-win-x64.$env:DOTNET_CLI_VERSION.msi"
$DotnetBundleOutput = Join-Path $PackageDir "dotnet-win-x64.$env:DOTNET_CLI_VERSION.exe"
$DotnetMSIOutput = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$env:DOTNET_CLI_VERSION.msi"
$DotnetBundleOutput = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$env:DOTNET_CLI_VERSION.exe"
Write-Host "Creating dotnet MSI at $DotnetMSIOutput"
Write-Host "Creating dotnet Bundle at $DotnetBundleOutput"

View file

@ -26,7 +26,7 @@
<?if $(var.Platform)=x86?>
<?define Program_Files="ProgramFilesFolder"?>
<?define Win64AttributeValue=no?>
<?define UpgradeCode="70A1576F-63B6-4659-9E39-25C7B769DDE5"?>
<?define UpgradeCode="25CAE344-22A6-422D-942E-942687C56A45"?>
<?elseif $(var.Platform)=x64?>
<?define Program_Files="ProgramFiles64Folder"?>
<?define Win64AttributeValue=yes?>

View file

@ -14,6 +14,8 @@ namespace Microsoft.DotNet.Cli.Build
{
public static readonly string CoreCLRVersion = "1.0.1-rc2-23811";
public static readonly string AppDepSdkVersion = "1.0.6-prerelease-00003";
public static readonly bool IsWinx86 = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
RuntimeInformation.ProcessArchitecture == Architecture.X86;
public static readonly List<string> AssembliesToCrossGen = GetAssembliesToCrossGen();
@ -60,16 +62,18 @@ namespace Microsoft.DotNet.Cli.Build
Mkdirp(cmakeOut);
var configuration = c.BuildContext.Get<string>("Configuration");
var architecture = PlatformServices.Default.Runtime.RuntimeArchitecture;
// Run the build
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Why does Windows directly call cmake but Linux/Mac calls "build.sh" in the corehost dir?
// See the comment in "src/corehost/build.sh" for details. It doesn't work for some reason.
var visualStudio = IsWinx86 ? "Visual Studio 14 2015" : "Visual Studio 14 2015 Win64";
ExecIn(cmakeOut, "cmake",
Path.Combine(c.BuildContext.BuildDirectory, "src", "corehost"),
"-G",
"Visual Studio 14 2015 Win64");
visualStudio);
var pf32 = RuntimeInformation.OSArchitecture == Architecture.X64 ?
Environment.GetEnvironmentVariable("ProgramFiles(x86)") :
@ -203,6 +207,25 @@ namespace Microsoft.DotNet.Cli.Build
File.Delete(Path.Combine(binDir, $"dotnet{Constants.ExeSuffix}"));
File.Copy(Path.Combine(binDir, $"corehost{Constants.ExeSuffix}"), Path.Combine(binDir, $"dotnet{Constants.ExeSuffix}"));
// HACK
// bootstrapping for Windows x86. Copy csc/vbc from stage0.
// This is a temporary hack for https://github.com/dotnet/roslyn/issues/8951
if (IsWinx86)
{
List<string> x86compilerBins = new List<string> {
"csc.dll",
"Microsoft.CodeAnalysis.CSharp.dll",
"Microsoft.CodeAnalysis.dll",
"Microsoft.CodeAnalysis.VisualBasic.dll",
"vbc.dll"
};
foreach (var binary in x86compilerBins)
{
File.Copy(Path.Combine(DotNetCli.Stage0.BinPath, binary), Path.Combine(binDir, binary), true);
}
}
// Crossgen Roslyn
var result = Crossgen(c, binDir);
if (!result.Success)
@ -233,8 +256,16 @@ namespace Microsoft.DotNet.Cli.Build
// Find toolchain package
string packageId;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (IsWinx86)
{
// https://github.com/dotnet/cli/issues/1550
c.Warn("Native compilation is not yet working on Windows x86");
return c.Success();
}
packageId = "toolchain.win7-x64.Microsoft.DotNet.AppDep";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
@ -282,10 +313,11 @@ namespace Microsoft.DotNet.Cli.Build
}
// Find crossgen
string arch = PlatformServices.Default.Runtime.RuntimeArchitecture;
string packageId;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
packageId = "runtime.win7-x64.Microsoft.NETCore.Runtime.CoreCLR";
packageId = $"runtime.win7-{arch}.Microsoft.NETCore.Runtime.CoreCLR";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{

View file

@ -27,6 +27,7 @@ namespace Microsoft.DotNet.Cli.Build
// 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 = PlatformServices.Default.Runtime.RuntimeArchitecture;
var env = new Dictionary<string, string>()
{
{ "RID", PlatformServices.Default.Runtime.GetRuntimeIdentifier() },
@ -50,7 +51,8 @@ namespace Microsoft.DotNet.Cli.Build
{ "DOTNET_CLI_VERSION", buildVersion.SimpleVersion },
{ "DOTNET_MSI_VERSION", buildVersion.GenerateMsiVersion() },
{ "VersionSuffix", buildVersion.VersionSuffix },
{ "CONFIGURATION", configuration }
{ "CONFIGURATION", configuration },
{ "ARCHITECTURE", architecture }
};
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))

View file

@ -35,7 +35,9 @@ namespace Microsoft.DotNet.Cli.Build
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0", PlatformServices.Default.Runtime.OperatingSystemPlatform.ToString(), "cli", "bin");
return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0",
PlatformServices.Default.Runtime.OperatingSystemPlatform.ToString(),
PlatformServices.Default.Runtime.RuntimeArchitecture, "cli", "bin");
}
else
{

View file

@ -5,7 +5,8 @@
param(
[string]$Channel="dev",
[string]$version="Latest"
[string]$version="Latest",
[string]$Architecture="x64"
)
$ErrorActionPreference="Stop"
@ -16,7 +17,7 @@ if ($fileVersion -eq "Latest") {
$fileVersion = "latest"
}
$Feed="https://dotnetcli.blob.core.windows.net/dotnet"
$DotNetFileName="dotnet-win-x64.$fileVersion.zip"
$DotNetFileName="dotnet-win-$Architecture.$fileVersion.zip"
$DotNetUrl="$Feed/$Channel/Binaries/$Version"
function say($str)
@ -42,7 +43,7 @@ if (Test-Path $LocalFile)
{
if ($Version -eq "Latest")
{
$RemoteResponse = Invoke-WebRequest -UseBasicParsing "$Feed/$Channel/dnvm/latest.win.version"
$RemoteResponse = Invoke-WebRequest -UseBasicParsing "$Feed/$Channel/dnvm/latest.win.$Architecture.version"
$RemoteData = @([Text.Encoding]::UTF8.GetString($RemoteResponse.Content).Split([char[]]@(), [StringSplitOptions]::RemoveEmptyEntries));
$RemoteHash = $RemoteData[0].Trim()
$RemoteVersion = $RemoteData[1].Trim()

View file

@ -26,7 +26,7 @@ $PackageVersion
$VersionContent | Out-File -Encoding UTF8 "$Stage2Dir\.version"
$PackageName = Join-Path $PackageDir "dotnet-win-x64.$PackageVersion.zip"
$PackageName = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$PackageVersion.zip"
if (Test-Path $PackageName)
{

View file

@ -98,30 +98,16 @@ function UploadBinaries($zipFile)
}
Write-Host "Updating the latest dotnet binaries for windows.."
$zipBlobLatest = "$env:CHANNEL/Binaries/Latest/dotnet-win-x64.latest.zip"
$zipBlobLatest = "$env:CHANNEL/Binaries/Latest/dotnet-win-$env:ARCHITECTURE.latest.zip"
if(-Not (UploadFile $zipBlobLatest $zipFile $true))
{
return -1
}
# update the index file too
$indexContent = "Binaries/$env:DOTNET_CLI_VERSION/$fileName"
$indexFile = "$env:TEMP\latest.win.index"
$indexContent | Out-File -FilePath $indexFile
# upload the index file
$indexBlob = "$env:CHANNEL/dnvm/latest.win.index"
if(-Not (UploadFile $indexBlob $indexFile $true))
{
return -1
}
# update the version file
$versionFile = Convert-Path $PSScriptRoot\..\..\artifacts\$env:RID\stage2\.version
$versionBlob = "$env:CHANNEL/dnvm/latest.win.version"
$versionBlob = "$env:CHANNEL/dnvm/latest.win.$env:ARCHITECTURE.version"
if(-Not (UploadFile $versionBlob $versionFile $true))
{
@ -142,7 +128,7 @@ function UploadInstallers($installerFile)
}
Write-Host "Updating the latest dotnet installer for windows.."
$installerBlobLatest = "$env:CHANNEL/Installers/Latest/dotnet-win-x64.latest.exe"
$installerBlobLatest = "$env:CHANNEL/Installers/Latest/dotnet-win-$env:ARCHITECTURE.latest.exe"
if(-Not (UploadFile $installerBlobLatest $installerFile $true))
{

View file

@ -5,6 +5,7 @@
param(
[string]$Configuration="Debug",
[string]$Architecture="x64",
[switch]$NoPackage,
[switch]$Help)
@ -14,6 +15,7 @@ if($Help)
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 " -NoPackage Skip packaging targets"
Write-Host " -Help Display this help message"
Write-Host " <TARGETS...> The build targets to run (Init, Compile, Publish, etc.; Default is a full build and publish)"
@ -44,7 +46,7 @@ $env:CHANNEL=$env:RELEASE_SUFFIX
# 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="$PSScriptRoot\..\.dotnet_stage0\Windows"
$env:DOTNET_INSTALL_DIR="$PSScriptRoot\..\.dotnet_stage0\Windows\$Architecture"
}
if (!(Test-Path $env:DOTNET_INSTALL_DIR))
@ -54,7 +56,7 @@ if (!(Test-Path $env:DOTNET_INSTALL_DIR))
# Install a stage 0
Write-Host "Installing .NET Core CLI Stage 0 from beta channel"
& "$PSScriptRoot\obtain\install.ps1" -Channel $env:CHANNEL
& "$PSScriptRoot\obtain\install.ps1" -Channel $env:CHANNEL -Architecture $Architecture
# Put the stage0 on the path
$env:PATH = "$env:DOTNET_INSTALL_DIR\cli\bin;$env:PATH"

View file

@ -2,7 +2,9 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.DotNet.Cli.Utils;
using NugetProgram = NuGet.CommandLine.XPlat.Program;
namespace Microsoft.DotNet.Tools.Restore
{
@ -20,22 +22,16 @@ namespace Microsoft.DotNet.Tools.Restore
var result = Run(Enumerable.Concat(
prefixArgs,
args))
.ForwardStdOut()
.ForwardStdErr()
.Execute();
args).ToArray());
return result.ExitCode;
return result;
}
private static Command Run(IEnumerable<string> nugetArgs)
private static int Run(string[] nugetArgs)
{
var corerun = Path.Combine(
AppContext.BaseDirectory,
"corerun" + Constants.ExeSuffix);
return Command.Create(corerun, Enumerable.Concat(
new[] { Path.Combine(AppContext.BaseDirectory, "NuGet.CommandLine.XPlat.dll") },
nugetArgs));
var nugetAsm = typeof(NugetProgram).GetTypeInfo().Assembly;
var mainMethod = nugetAsm.EntryPoint;
return (int)mainMethod.Invoke(null, new object[] { nugetArgs });
}
}
}

View file

@ -89,6 +89,12 @@ namespace Microsoft.DotNet.Tests.EndToEnd
return;
}
if (IsWinX86())
{
Console.WriteLine("Skipping native compilation tests on Windows x86 - https://github.com/dotnet/cli/issues/1550");
return;
}
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, framework: DefaultFramework);
buildCommand.Execute().Should().Pass();
@ -105,6 +111,12 @@ namespace Microsoft.DotNet.Tests.EndToEnd
return;
}
if (IsWinX86())
{
Console.WriteLine("Skipping native compilation tests on Windows x86 - https://github.com/dotnet/cli/issues/1550");
return;
}
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, nativeCppMode: true, framework: DefaultFramework);
buildCommand.Execute().Should().Pass();
@ -121,6 +133,12 @@ namespace Microsoft.DotNet.Tests.EndToEnd
return;
}
if (IsWinX86())
{
Console.WriteLine("Skipping native compilation tests on Windows x86 - https://github.com/dotnet/cli/issues/1550");
return;
}
// first build
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, nativeCppMode: true, framework: DefaultFramework);
var binariesOutputDirectory = GetCompilationOutputPath(OutputDirectory, false);
@ -233,6 +251,12 @@ namespace Microsoft.DotNet.Tests.EndToEnd
return false;
}
private bool IsWinX86()
{
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
RuntimeInformation.ProcessArchitecture == Architecture.X86;
}
private static DateTime GetLastWriteTimeUtcOfDirectoryFiles(string outputDirectory)
{
return Directory.EnumerateFiles(outputDirectory).Max(f => File.GetLastWriteTimeUtc(f));