Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .ado/VSComponentList.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
$dir = $env:temp
if ($env:Agent_TempDirectory -ne $null)
{
$dir = $env:Agent_TempDirectory
}

$installerPath = 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\'
$installationPath = . $installerPath\vswhere.exe -latest -property installationPath
$vsconfig = "$dir\vsconfig"
Write-Host "VSConfig will be at $vsconfig"

Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/c4fef23e-cc45-4836-9544-70e213134bc8/1ee5717e9a1e05015756dff77eb27d554a79a6db91f2716d836df368381af9a1/vs_Enterprise.exe' -OutFile $dir\vs_enterprise.exe
$p = Start-Process -PassThru $dir\vs_enterprise.exe -RedirectStandardError $dir\err -RedirectStandardOutput $dir\out -ArgumentList "export --installpath `"$installationPath`" --quiet --config $vsconfig"
$p.WaitForExit()
$x = [Datetime]::Now.AddSeconds(60)
while (!(Test-Path $vsconfig) -and ([datetime]::Now -lt $x))
{
Sleep 5
Write-Host "Waiting for vsconfig file..."
}

Get-Content $dir\err
Get-Content $dir\out
Get-Content $vsconfig
2 changes: 1 addition & 1 deletion .ado/windows-vs-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ jobs:
vmImage: windows-2019
BuildPlatform: x64
UseRNFork: true
vsComponents: Microsoft.VisualStudio.Component.VC.v141.x86.x64
vsComponents: Microsoft.VisualStudio.Component.VC.v141.x86.x64, Microsoft.VisualStudio.ComponentGroup.UWP.VC.v141

- job: RNWNugetPR
displayName: Build and Pack Nuget
Expand Down
9 changes: 9 additions & 0 deletions change/react-native-windows-2019-10-15-18-17-54-v141path.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "none",
"comment": "Don't hardcode the path to v141 platform toolset",
"packageName": "react-native-windows",
"email": "asklar@winse.microsoft.com",
"commit": "5259e65b49ff7d0131cc7d731ca7bd3438b03776",
"date": "2019-10-16T01:17:54.674Z",
"file": "F:\\rnw\\change\\react-native-windows-2019-10-15-18-17-54-v141path.json"
}
16 changes: 12 additions & 4 deletions vnext/local-cli/runWindows/utils/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ async function buildSolution(slnFile, buildType, buildArch, verbose) {
);
}

const msBuildTools = MSBuildTools.findAvailableVersion();
const msBuildTools = MSBuildTools.findAvailableVersion(buildArch, verbose);
await msBuildTools.buildProject(slnFile, buildType, buildArch, null, verbose);
}

async function nugetRestore(nugetPath, slnFile, verbose) {
async function nugetRestore(nugetPath, slnFile, verbose, msbuildVersion) {
const text = 'Restoring NuGets';
const spinner = newSpinner(text);

console.log(nugetPath);
await commandWithProgress(
spinner,
text,
Expand All @@ -43,6 +43,8 @@ async function nugetRestore(nugetPath, slnFile, verbose) {
'-NonInteractive',
'-Verbosity',
verbose ? 'normal' : 'quiet',
'-MSBuildVersion',
msbuildVersion,
],
verbose,
);
Expand All @@ -68,7 +70,13 @@ async function restoreNuGetPackages(options, slnFile, verbose) {
}
ensureNugetSpinner.succeed('Found NuGet Binary');

await nugetRestore(nugetPath, slnFile, verbose);
const msbuildTools = MSBuildTools.findAvailableVersion('x86', verbose);
await nugetRestore(
nugetPath,
slnFile,
verbose,
msbuildTools.installationVersion,
);
}

function getSolutionFile(options) {
Expand Down
157 changes: 113 additions & 44 deletions vnext/local-cli/runWindows/utils/msbuildtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
// @ts-check
'use strict';

const EOL = require('os').EOL;
const fs = require('fs');
const path = require('path');
Expand All @@ -25,16 +24,20 @@ const {
const MSBUILD_VERSIONS = ['16.0', '15.0', '14.0', '12.0', '4.0'];

class MSBuildTools {
constructor(version, localPath) {
// version is something like 16.0 for 2019
// localPath is the path to MSBuild.exe (x86)
// installationVersion is the full version e.g. 16.3.29411.108
constructor(version, localPath, installationVersion) {
this.version = version;
this.path = localPath;
this.installationVersion = installationVersion;
}

cleanProject(slnFile) {
const cmd = `"${path.join(
this.path,
'msbuild.exe',
)}" "${slnFile}" t/:Clean`;
)}" "${slnFile}" /t:Clean`;
const results = child_process
.execSync(cmd)
.toString()
Expand All @@ -57,19 +60,13 @@ class MSBuildTools {
'/p:AppxBundle=Never',
];

args.push('/p:PlatformToolset=v141');

// Set platform toolset for VS 2017 (this way we can keep the base sln file working for VS 2015)
if (this.version === '15.0') {
args.push('/p:PlatformToolset=v141');
args.push('/p:VisualStudioVersion=15.0');
}

// Set platform toolset for VS 2019
if (this.version === '16.0') {
args.push('/p:PlatformToolset=v141');
} else if (this.version === '16.0') {
args.push('/p:VisualStudioVersion=16.0');
args.push(
'/p:VCTargetsPath=C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Microsoft\\VC\\v150\\',
);
}

if (config) {
Expand All @@ -85,6 +82,8 @@ class MSBuildTools {
return;
}

console.log(`Running MSBuild with args ${args.join(' ')}`);

const progressName = 'Building Solution';
const spinner = newSpinner(progressName);
await commandWithProgress(
Expand All @@ -97,9 +96,7 @@ class MSBuildTools {
}
}

function checkMSBuildVersion(version) {
let toolsPath = null;

function VSWhere(requires, version, property) {
// This path is maintained and VS has promised to keep it valid.
const vsWherePath = path.join(
process.env['ProgramFiles(x86)'],
Expand All @@ -110,70 +107,142 @@ function checkMSBuildVersion(version) {
if (fs.existsSync(vsWherePath)) {
const vsPath = child_process
.execSync(
`"${vsWherePath}" -latest -products * Microsoft.Component.MSBuild -property installationPath`,
`"${vsWherePath}" -version [${version},${Number(version) +
1}) -products * -requires ${requires} -property ${property}`,
)
.toString()
.split(EOL)[0];

// VS 2019 changed path naming convention
const vsVersion = version === '16.0' ? 'Current' : version;

// look for the specified version of msbuild
const msBuildPath = path.join(
vsPath,
'MSBuild',
vsVersion,
'Bin/MSBuild.exe',
);

toolsPath = fs.existsSync(msBuildPath) ? path.dirname(msBuildPath) : null;
return vsPath;
} else {
const query = `reg query HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\${version} /s /v MSBuildToolsPath`;
let toolsPath = null;
// Try to get the MSBuild path using registry
try {
const output = child_process.execSync(query).toString();
let toolsPathOutput = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output);
if (toolsPathOutput) {
toolsPathOutput = toolsPathOutput[1];
let toolsPathOutputStr = toolsPathOutput[1];
// Win10 on .NET Native uses x86 arch compiler, if using x64 Node, use x86 tools
if (
version === '15.0' ||
(version === '14.0' && toolsPath.indexOf('amd64') > -1)
(version === '14.0' && toolsPathOutputStr.indexOf('amd64') > -1)
) {
toolsPathOutput = path.resolve(toolsPathOutput, '..');
toolsPathOutputStr = path.resolve(toolsPathOutputStr, '..');
}
toolsPath = toolsPathOutput;
toolsPath = toolsPathOutputStr;
}
} catch (e) {
toolsPath = null;
}
return toolsPath;
}
}

function getVC141Component(version, buildArch) {
if (version === '16.0') {
switch (buildArch.toLowerCase()) {
case 'x86':
case 'x64':
return 'Microsoft.VisualStudio.Component.VC.v141.x86.x64';
case 'arm':
return 'Microsoft.VisualStudio.Component.VC.v141.ARM';
case 'arm64':
return 'Microsoft.VisualStudio.Component.VC.v141.ARM64';
}
} else {
switch (buildArch.toLowerCase()) {
case 'x86':
case 'x64':
return 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64';
case 'arm':
return 'Microsoft.VisualStudio.Component.VC.Tools.ARM';
case 'arm64':
return 'Microsoft.VisualStudio.Component.VC.Tools.ARM64';
}
}
}

function checkMSBuildVersion(version, buildArch, verbose) {
let toolsPath = null;
if (verbose) {
console.log('Searching for MSBuild version ' + version);
}

// https://aka.ms/vs/workloads
const requires16 = [
'Microsoft.Component.MSBuild',
getVC141Component(version, buildArch),
'Microsoft.VisualStudio.ComponentGroup.UWP.VC.v141',
];
const requires15 = [
'Microsoft.Component.MSBuild',
getVC141Component(version, buildArch),
'Microsoft.VisualStudio.ComponentGroup.UWP.VC',
];

const requires = version === '16.0' ? requires16 : requires15;

const vsPath = VSWhere(requires.join(' '), version, 'installationPath');
const installationVersion = VSWhere(
requires.join(' '),
version,
'installationVersion',
);
// VS 2019 changed path naming convention
const vsVersion = version === '16.0' ? 'Current' : version;

// look for the specified version of msbuild
const msBuildPath = path.join(
vsPath,
'MSBuild',
vsVersion,
'Bin/MSBuild.exe',
);

toolsPath = fs.existsSync(msBuildPath) ? path.dirname(msBuildPath) : null;

// We found something so return MSBuild Tools.
if (toolsPath) {
newSuccess(`Found MSBuild v${version} at ${toolsPath}`);
return new MSBuildTools(version, toolsPath);
newSuccess(
`Found MSBuild v${version} at ${toolsPath} (${installationVersion})`,
);
return new MSBuildTools(version, toolsPath, installationVersion);
} else {
return null;
}
}

module.exports.findAvailableVersion = function() {
const versions = MSBUILD_VERSIONS.map(checkMSBuildVersion);
module.exports.findAvailableVersion = function(buildArch, verbose) {
const versions =
process.env.VisualStudioVersion != null
? [
checkMSBuildVersion(
process.env.VisualStudioVersion,
buildArch,
verbose,
),
]
: MSBUILD_VERSIONS.map(function(value) {
return checkMSBuildVersion(value, buildArch, verbose);
});
const msbuildTools = versions.find(Boolean);

if (!msbuildTools) {
throw new Error('MSBuild tools not found');
if (process.env.VisualStudioVersion != null) {
throw new Error(
`MSBuild tools not found for version ${
process.env.VisualStudioVersion
} (from environment). Make sure all required components have been installed (e.g. v141 support)`,
);
} else {
throw new Error(
'MSBuild tools not found. Make sure all required components have been installed (e.g. v141 support)',
);
}
}

return msbuildTools;
};

module.exports.findAllAvailableVersions = function() {
console.log(chalk.green('Searching for available MSBuild versions...'));
return MSBUILD_VERSIONS.map(checkMSBuildVersion).filter(item => !!item);
};

module.exports.getAllAvailableUAPVersions = function() {
const results = [];

Expand Down