Skip to content

Commit

Permalink
.Net core x86 support (#2161)
Browse files Browse the repository at this point in the history
Using the apphost sdk feature to enable the x86 support for .Net core projects.
  • Loading branch information
singhsarab committed Sep 11, 2019
1 parent 32a75bd commit 96bb81e
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 38 deletions.
25 changes: 22 additions & 3 deletions scripts/build.ps1
Expand Up @@ -95,6 +95,9 @@ $TPB_TargetFrameworkUap = "uap10.0"
$TPB_TargetFrameworkNS2_0 = "netstandard2.0"
$TPB_Configuration = $Configuration
$TPB_TargetRuntime = $TargetRuntime
$TPB_X64_Runtime = "win7-x64"
$TPB_X86_Runtime = "win7-x86"

# Version suffix is empty for RTM releases
$TPB_Version = if ($VersionSuffix -ne '') { $Version + "-" + $VersionSuffix } else { $Version }
$TPB_CIBuild = $CIBuild
Expand Down Expand Up @@ -223,6 +226,8 @@ function Publish-Package
$testHostx86Project = Join-Path $env:TP_ROOT_DIR "src\testhost.x86\testhost.x86.csproj"
$testhostFullPackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFramework\$TPB_TargetRuntime")
$testhostCorePackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkCore20")
$testhostCorePackageX64Dir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkCore20\$TPB_X64_Runtime")
$testhostCorePackageX86Dir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkCore20\$TPB_X86_Runtime")
$testhostUapPackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkUap")
$vstestConsoleProject = Join-Path $env:TP_ROOT_DIR "src\vstest.console\vstest.console.csproj"
$settingsMigratorProject = Join-Path $env:TP_ROOT_DIR "src\SettingsMigrator\SettingsMigrator.csproj"
Expand Down Expand Up @@ -252,10 +257,12 @@ function Publish-Package
Publish-PackageInternal $testHostProject $TPB_TargetFramework $testhostFullPackageDir
Publish-PackageInternal $testHostProject $TPB_TargetFrameworkCore20 $testhostCorePackageDir
Publish-PackageInternal $testHostProject $TPB_TargetFrameworkCore20 $testhostUapPackageDir
Publish-PackageWithRuntimeInternal $testHostProject $TPB_TargetFrameworkCore20 $TPB_X64_Runtime false $testhostCorePackageX64Dir

Write-Log "Package: Publish testhost.x86\testhost.x86.csproj"
Publish-PackageInternal $testHostx86Project $TPB_TargetFramework $testhostFullPackageDir

Publish-PackageInternal $testHostx86Project $TPB_TargetFramework $testhostFullPackageDir
Publish-PackageWithRuntimeInternal $testHostx86Project $TPB_TargetFrameworkCore20 $TPB_X86_Runtime false $testhostCorePackageX86Dir

# Copy over the Full CLR built testhost package assemblies to the Core CLR and Full CLR package folder.
$coreCLRFull_Dir = "TestHost"
$fullDestDir = Join-Path $coreCLR20PackageDir $coreCLRFull_Dir
Expand Down Expand Up @@ -292,6 +299,7 @@ function Publish-Package
$extensions_Dir = "Extensions"
$fullCLRExtensionsDir = Join-Path $fullCLRPackageDir $extensions_Dir
$coreCLRExtensionsDir = Join-Path $coreCLR20PackageDir $extensions_Dir

# Create an extensions directory.
New-Item -ItemType directory -Path $fullCLRExtensionsDir -Force | Out-Null
New-Item -ItemType directory -Path $coreCLRExtensionsDir -Force | Out-Null
Expand Down Expand Up @@ -437,6 +445,14 @@ function Publish-PackageInternal($packagename, $framework, $output)
Set-ScriptFailedOnError
}

function Publish-PackageWithRuntimeInternal($packagename, $framework, $runtime, $selfcontained, $output)
{
Write-Verbose "$dotnetExe publish $packagename --configuration $TPB_Configuration --framework $framework --runtime $runtime --output $output -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild"
& $dotnetExe publish $packagename --configuration $TPB_Configuration --framework $framework --runtime $runtime --self-contained $selfcontained --output $output -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild

Set-ScriptFailedOnError
}

function Copy-Loc-Files($sourceDir, $destinationDir, $dllName)
{
foreach($lang in $language) {
Expand Down Expand Up @@ -582,7 +598,10 @@ function Create-NugetPackages
$testhostUapPackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkUap")
Copy-Item $tpNuspecDir\uap\"Microsoft.TestPlatform.TestHost.Uap.props" $testhostUapPackageDir\Microsoft.TestPlatform.TestHost.props -Force
Copy-Item $tpNuspecDir\uap\"Microsoft.TestPlatform.TestHost.Uap.targets" $testhostUapPackageDir\Microsoft.TestPlatform.TestHost.targets -Force


$testhostCorePackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkCore20")
Copy-Item $tpNuspecDir\"Microsoft.TestPlatform.TestHost.NetCore.props" $testhostCorePackageDir\Microsoft.TestPlatform.TestHost.props -Force

# Call nuget pack on these components.
$nugetExe = Join-Path $env:TP_PACKAGES_DIR -ChildPath "Nuget.CommandLine" | Join-Path -ChildPath $env:NUGET_EXE_Version | Join-Path -ChildPath "tools\NuGet.exe"

Expand Down
2 changes: 1 addition & 1 deletion scripts/verify-nupkgs.ps1
Expand Up @@ -20,7 +20,7 @@ function Verify-Nuget-Packages($packageDirectory)
"Microsoft.TestPlatform.Extensions.TrxLogger" = 33;
"Microsoft.TestPlatform.ObjectModel" = 62;
"Microsoft.TestPlatform.Portable" = 502;
"Microsoft.TestPlatform.TestHost" = 140;
"Microsoft.TestPlatform.TestHost" = 145;
"Microsoft.TestPlatform.TranslationLayer" = 121}

$nugetPackages = Get-ChildItem -Filter "*.nupkg" $packageDirectory | % { $_.FullName}
Expand Down
Expand Up @@ -10,6 +10,7 @@
<TargetFrameworks Condition=" '$(DotNetBuildFromSource)' == 'true' ">netstandard2.0;netcoreapp2.1</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableCodeAnalysis>true</EnableCodeAnalysis>
<NoWarn>NU1605</NoWarn>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
Expand Down
Expand Up @@ -48,7 +48,7 @@ public class DotnetTestHostManager : ITestRuntimeProvider
private const string DataCollectorRegexPattern = @"Collector.dll";

private IDotnetHostHelper dotnetHostHelper;

private IEnvironment platformEnvironment;
private IProcessHelper processHelper;

private IFileHelper fileHelper;
Expand All @@ -65,11 +65,13 @@ public class DotnetTestHostManager : ITestRuntimeProvider

private string hostPackageVersion = "15.0.0";

private Architecture architecture;

/// <summary>
/// Initializes a new instance of the <see cref="DotnetTestHostManager"/> class.
/// </summary>
public DotnetTestHostManager()
: this(new ProcessHelper(), new FileHelper(), new DotnetHostHelper())
: this(new ProcessHelper(), new FileHelper(), new DotnetHostHelper(), new PlatformEnvironment())
{
}

Expand All @@ -79,14 +81,17 @@ public DotnetTestHostManager()
/// <param name="processHelper">Process helper instance.</param>
/// <param name="fileHelper">File helper instance.</param>
/// <param name="dotnetHostHelper">DotnetHostHelper helper instance.</param>
/// <param name="platformEnvironment">Platform Environment</param>
internal DotnetTestHostManager(
IProcessHelper processHelper,
IFileHelper fileHelper,
IDotnetHostHelper dotnetHostHelper)
IDotnetHostHelper dotnetHostHelper,
IEnvironment platformEnvironment)
{
this.processHelper = processHelper;
this.fileHelper = fileHelper;
this.dotnetHostHelper = dotnetHostHelper;
this.platformEnvironment = platformEnvironment;
}

/// <inheritdoc />
Expand Down Expand Up @@ -135,6 +140,9 @@ public void Initialize(IMessageLogger logger, string runsettingsXml)
{
this.messageLogger = logger;
this.hostExitedEventRaised = false;

var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettingsXml);
this.architecture = runConfiguration.TargetPlatform;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -163,25 +171,8 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn
{
var startInfo = new TestProcessStartInfo();

var currentProcessPath = this.processHelper.GetCurrentProcessFileName();

// This host manager can create process start info for dotnet core targets only.
// If already running with the dotnet executable, use it; otherwise pick up the dotnet available on path.
// Wrap the paths with quotes in case dotnet executable is installed on a path with whitespace.
if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase)
|| currentProcessPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase))
{
startInfo.FileName = currentProcessPath;
}
else
{
startInfo.FileName = this.dotnetHostHelper.GetDotnetPath();
}

EqtTrace.Verbose("DotnetTestHostmanager: Full path of dotnet.exe is {0}", startInfo.FileName);

// .NET core host manager is not a shared host. It will expect a single test source to be provided.
var args = "exec";
var args = string.Empty;
var sourcePath = sources.Single();
var sourceFile = Path.GetFileNameWithoutExtension(sourcePath);
var sourceDirectory = Path.GetDirectoryName(sourcePath);
Expand Down Expand Up @@ -212,11 +203,41 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn
EqtTrace.Verbose("DotnetTestHostmanager: File {0}, doesnot exist", depsFilePath);
}

var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
var testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
// If Testhost.exe is available use it
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
var fullExePath = Path.Combine(sourceDirectory, exeName);
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows) && this.fileHelper.Exists(fullExePath))
{
startInfo.FileName = fullExePath;
}
else
{
var currentProcessPath = this.processHelper.GetCurrentProcessFileName();

// This host manager can create process start info for dotnet core targets only.
// If already running with the dotnet executable, use it; otherwise pick up the dotnet available on path.
// Wrap the paths with quotes in case dotnet executable is installed on a path with whitespace.
if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase)
|| currentProcessPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase))
{
startInfo.FileName = currentProcessPath;
}
else
{
startInfo.FileName = this.dotnetHostHelper.GetDotnetPath();
}

var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
var testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);

EqtTrace.Verbose("DotnetTestHostmanager: Full path of testhost.dll is {0}", testHostPath);
args = "exec" + args;
args += " " + testHostPath.AddDoubleQuote();
}

EqtTrace.Verbose("DotnetTestHostmanager: Full path of host exe is {0}", startInfo.FileName);

EqtTrace.Verbose("DotnetTestHostmanager: Full path of testhost.dll is {0}", testHostPath);
args += " " + testHostPath.AddDoubleQuote() + " " + connectionInfo.ToCommandLineOptions();
args += " " + connectionInfo.ToCommandLineOptions();

// Create a additional probing path args with Nuget.Client
// args += "--additionalprobingpath xxx"
Expand Down
27 changes: 27 additions & 0 deletions src/package/nuspec/Microsoft.TestPlatform.TestHost.NetCore.props
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" '$(Platform)' == 'x86' AND '$(OS)' == 'Windows_NT'">
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.exe">
<Link>testhost.x86.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.dll">
<Link>testhost.x86.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(Platform)' == 'x64' AND '$(OS)' == 'Windows_NT'" >
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.exe">
<Link>testhost.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.dll">
<Link>testhost.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</Project>
11 changes: 9 additions & 2 deletions src/package/nuspec/TestPlatform.TestHost.nuspec
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
<package >
<metadata>
<id>Microsoft.TestPlatform.TestHost</id>
Expand Down Expand Up @@ -41,7 +41,14 @@
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\testhost.deps.json" target="lib\netcoreapp2.1\" />
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\x86\msdia140.dll" target="lib\netcoreapp2.1\x86\" />
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\x64\msdia140.dll" target="lib\netcoreapp2.1\x64\" />


<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\win7-x64\testhost.dll" target="build\netcoreapp2.1\x64" />
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\win7-x64\testhost.exe" target="build\netcoreapp2.1\x64" />
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\win7-x86\testhost.x86.dll" target="build\netcoreapp2.1\x86\" />
<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\win7-x86\testhost.x86.exe" target="build\netcoreapp2.1\x86\" />

<file src="Microsoft.TestPlatform.TestHost\netcoreapp2.1\Microsoft.TestPlatform.TestHost.props" target="build\netcoreapp2.1\" />

<!-- UWP -->
<file src="Microsoft.TestPlatform.TestHost\uap10.0\testhost.dll" target="lib\uap10.0\" />
<file src="Microsoft.TestPlatform.TestHost\uap10.0\Microsoft.TestPlatform.CommunicationUtilities.dll" target="lib\uap10.0\" />
Expand Down
2 changes: 0 additions & 2 deletions src/testhost.x86/testhost.x86.csproj
Expand Up @@ -13,8 +13,6 @@
<Prefer32Bit>true</Prefer32Bit>
<OutputType>Exe</OutputType>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
</PropertyGroup>
Expand Down
Expand Up @@ -528,7 +528,7 @@ private class TestableDotnetTestHostManager : DotnetTestHostManager
bool checkRequired,
IProcessHelper processHelper,
IFileHelper fileHelper,
IEnvironment environment) : base(processHelper, fileHelper, new DotnetHostHelper(fileHelper, environment))
IEnvironment environment) : base(processHelper, fileHelper, new DotnetHostHelper(fileHelper, environment), environment)
{
this.isVersionCheckRequired = checkRequired;
}
Expand Down

0 comments on commit 96bb81e

Please sign in to comment.