Merge remote-tracking branch 'Microsoft/master' into xplat

This commit is contained in:
Rainer Sigwald 2016-05-16 14:08:30 -05:00
Родитель 553fb3a5e6 ea6af14a87
Коммит 0a3eb9b25c
114 изменённых файлов: 2280 добавлений и 1468 удалений

2
.gitattributes поставляемый
Просмотреть файл

@ -64,4 +64,4 @@
# Force bash scripts to always use lf line endings so that if a repro is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf
*.sh text eol=lf

Просмотреть файл

@ -25,15 +25,26 @@ echo ** Additional Build Parameters:%AdditionalBuildCommand%
echo.
:: Build MSBuild
call "%~dp0build.cmd" /t:Rebuild %AdditionalBuildCommand%
set BUILDERRORLEVEL=%ERRORLEVEL%
:: Kill Roslyn, which may have handles open to files we want
taskkill /F /IM vbcscompiler.exe
if %BUILDERRORLEVEL% NEQ 0 (
echo.
echo Failed to build with errorlevel %BUILDERRORLEVEL% 1>&2
exit /b %BUILDERRORLEVEL%
)
:: Make a copy of our build
echo ** Copying bootstrapped MSBuild to the bootstrap folder
msbuild /v:m CreatePrivateMSBuildEnvironment.proj
echo.
msbuild /verbosity:minimal CreatePrivateMSBuildEnvironment.proj
if %ERRORLEVEL% NEQ 0 (
echo.
echo Failed building CreatePrivateMSBuildEnvironment.proj with error %ERRORLEVEL%
exit /b %ERRORLEVEL%
)
echo.
echo ** Packaging complete.
echo ** MSBuild = %~dp0\bin\bootstrap\14.1\MSBuild.exe
echo ** MSBuild = %~dp0\bin\bootstrap\15.0\MSBuild.exe

Просмотреть файл

@ -32,7 +32,7 @@
<Target Name="Build">
<!-- Copy in props and targets from the machine-installed MSBuildExtensionsPath -->
<Copy SourceFiles="@(InstalledVersionedExtensions)"
DestinationFiles="@(InstalledVersionedExtensions->'$(BootstrapDestination)14.1\%(RecursiveDir)%(Filename)%(Extension)')" />
DestinationFiles="@(InstalledVersionedExtensions->'$(BootstrapDestination)$(TargetMSBuildToolsVersion)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(InstalledMicrosoftExtensions)"
DestinationFiles="@(InstalledMicrosoftExtensions->'$(BootstrapDestination)Microsoft\%(RecursiveDir)%(Filename)%(Extension)')" />
@ -41,15 +41,15 @@
<!-- Delete shim projects, because they point where we can't follow. -->
<!-- It would be better to just not copy these. -->
<Delete Files="@(ShimTargets->'$(BootstrapDestination)14.1\Bin\%(FileName)%(Extension)')" />
<Delete Files="@(ShimTargets->'$(BootstrapDestination)$(TargetMSBuildToolsVersion)\Bin\%(FileName)%(Extension)')" />
<!-- Copy our binaries -->
<Copy SourceFiles="@(FreshlyBuiltBinaries)"
DestinationFolder="$(BootstrapDestination)14.1\Bin" />
DestinationFolder="$(BootstrapDestination)$(TargetMSBuildToolsVersion)\Bin" />
<!-- Copy our freshly-built props and targets, overwriting anything we copied from the machine -->
<Copy SourceFiles="@(FreshlyBuiltProjects)"
DestinationFolder="$(BootstrapDestination)14.1\Bin" />
DestinationFolder="$(BootstrapDestination)$(TargetMSBuildToolsVersion)\Bin" />
</Target>
<Target Name="CheckForBootstrap">

Просмотреть файл

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="dir.props" />
<Import Project="$(MicroBuildDir)MicroBuild.Core.props" />
<PropertyGroup>
<X86OutputPath>$(BaseOutputPath)X86\$(OS)\$(Configuration)\</X86OutputPath>
<X64OutputPath>$(BaseOutputPath)X64\$(OS)\$(Configuration)\</X64OutputPath>
<SetupPackageRoot>$(BinDir)Setup\</SetupPackageRoot>
<SetupPackageLayoutDir>$(SetupPackageRoot)layout\</SetupPackageLayoutDir>
<SetupPackageOutputFile>$(SetupPackageRoot)MSBuild.fopx</SetupPackageOutputFile>
</PropertyGroup>
<ItemGroup>
<BinX86Output Include="$(X86OutputPath)Microsoft.Build.dll" />
<BinX86Output Include="$(X86OutputPath)Microsoft.Build.Framework.dll" />
<BinX86Output Include="$(X86OutputPath)Microsoft.Build.Tasks.Core.dll" />
<BinX86Output Include="$(X86OutputPath)Microsoft.Build.Utilities.Core.dll" />
<BinX86Output Include="$(X86OutputPath)MSBuild.exe" />
<BinX86Output Include="$(X86OutputPath)MSBuild.exe.config" />
<BinX86Output Include="$(X86OutputPath)System.Threading.Tasks.Dataflow.dll" />
<BinX64Output Include="$(X64OutputPath)Microsoft.Build.dll" />
<BinX64Output Include="$(X64OutputPath)Microsoft.Build.Framework.dll" />
<BinX64Output Include="$(X64OutputPath)Microsoft.Build.Tasks.Core.dll" />
<BinX64Output Include="$(X64OutputPath)Microsoft.Build.Utilities.Core.dll" />
<BinX64Output Include="$(X64OutputPath)MSBuild.exe" />
<BinX64Output Include="$(X64OutputPath)MSBuild.exe.config" />
<BinX64Output Include="$(X64OutputPath)System.Threading.Tasks.Dataflow.dll" />
<CommonOutput Include="$(X86OutputPath)Microsoft.Common.CurrentVersion.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.Common.overridetasks" />
<CommonOutput Include="$(X86OutputPath)Microsoft.Common.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.Common.tasks" />
<CommonOutput Include="$(X86OutputPath)Microsoft.CSharp.Core.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.CSharp.CurrentVersion.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.CSharp.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.NetFramework.CurrentVersion.props" />
<CommonOutput Include="$(X86OutputPath)Microsoft.NetFramework.CurrentVersion.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.NetFramework.props" />
<CommonOutput Include="$(X86OutputPath)Microsoft.NetFramework.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.VisualBasic.CurrentVersion.targets" />
<CommonOutput Include="$(X86OutputPath)Microsoft.VisualBasic.targets" />
</ItemGroup>
<ItemGroup>
<PkgDef Include="$(SourceDir)Framework\Microsoft.Build.Framework.pkgdef" />
<PkgDef Include="$(SourceDir)XMakeBuildEngine\Microsoft.Build.pkgdef" />
<PkgDef Include="$(SourceDir)XmakeTasks\Microsoft.Build.Tasks.Core.pkgdef" />
<PkgDef Include="$(SourceDir)Utilities\Microsoft.Build.Utilities.Core.pkgdef" />
</ItemGroup>
<!-- Needed for the MicroBuild signing plugin -->
<ItemGroup>
<SigningTarget Include="$(SetupPackageOutputFile)"/>
<FilesToSign Include="@(SigningTarget)">
<Authenticode>Vsix</Authenticode>
</FilesToSign>
</ItemGroup>
<PropertyGroup>
<OutDir>$(SetupPackageRoot)</OutDir>
</PropertyGroup>
<Target Name="Build">
<Error Text="FopCreator.exe not found (MS internal only tool)."
Condition="!Exists('$(PackagesDir)\VS.Tools.Setup.FopCreator.1.0.16022601\FopCreator.exe')" />
<Error Text="X86 output folder not found."
Condition="!Exists('$(X86OutputPath)')" />
<Error Text="X64 output folder not found."
Condition="!Exists('$(X64OutputPath)')" />
<!-- Delete the output if exists -->
<RemoveDir Directories="$(SetupPackageRoot)" />
<!-- Copy our binaries to Bin and Bin\amd64 -->
<Copy SourceFiles="@(BinX86Output)"
DestinationFolder="$(SetupPackageLayoutDir)MSBuild\$(TargetMSBuildToolsVersion)\Bin" />
<Copy SourceFiles="@(CommonOutput)"
DestinationFolder="$(SetupPackageLayoutDir)MSBuild\$(TargetMSBuildToolsVersion)\Bin" />
<Copy SourceFiles="@(BinX64Output)"
DestinationFolder="$(SetupPackageLayoutDir)MSBuild\$(TargetMSBuildToolsVersion)\Bin\amd64" />
<Copy SourceFiles="@(CommonOutput)"
DestinationFolder="$(SetupPackageLayoutDir)MSBuild\$(TargetMSBuildToolsVersion)\Bin\amd64" />
<Copy SourceFiles="@(PkgDef)"
DestinationFolder="$(SetupPackageLayoutDir)Common7\IDE\CommonExtensions\MSBuild" />
<Exec Command="$(PackagesDir)\VS.Tools.Setup.FopCreator.1.0.16022601\FopCreator.exe /layoutdir $(SetupPackageLayoutDir) /outputfopx $(SetupPackageOutputFile)" />
<CallTarget Targets="AfterBuild" />
</Target>
<!-- MicroBuild signing plugin needs an AfterBuild target to run -->
<Target Name="AfterBuild" />
<Import Project="$(MicroBuildDir)MicroBuild.Core.targets" />
</Project>

Просмотреть файл

@ -1,4 +1,4 @@
# Microsoft.Build (MSBuild)
# Microsoft.Build (MSBuild)
The Microsoft Build Engine is a platform for building applications. This engine, which is also known as MSBuild, provides an XML schema for a project file that controls how the build platform processes and builds software. Visual Studio uses MSBuild, but MSBuild *does not* depend on Visual Studio. By invoking msbuild.exe on your project or solution file, you can orchestrate and build products in environments where Visual Studio isn't installed.
For more information on MSBuild, see the [MSDN documentation](https://msdn.microsoft.com/en-us/library/dd393574(v=vs.120).aspx).
@ -14,6 +14,7 @@ For more information on MSBuild, see the [MSDN documentation](https://msdn.micro
* Clone the sources: `git clone https://github.com/Microsoft/msbuild.git`
### Building
## Building MSBuild in VS 2015
For the full supported experience, you will need to have Visual Studio 2015. You can open the solution in Visual Studio 2013, but you will encounter issues building with the provided scripts.
To get started on **Visual Studio 2015**:
@ -26,6 +27,9 @@ To get started on **Visual Studio 2015**:
3. Restore NuGet packages: `msbuild /t:BulkRestoreNugetPackages build.proj`
4. Open src/MSBuild.sln solution in Visual Studio 2015.
## Building MSBuild in Unix (Mac & Linux)
MSBuild's xplat branch allows MSBuild to be run on Unix Systems. Set-up instructions can be viewed on the wiki: [Building Testing and Debugging on .Net Core MSBuild](https://github.com/Microsoft/msbuild/wiki/Building-Testing-and-Debugging-on-.Net-Core-MSBuild)
## How to Engage, Contribute and Provide Feedback
Before you contribute, please read through the contributing and developer guides to get an idea of what kinds of pull requests we will or won't accept.

Просмотреть файл

@ -7,16 +7,17 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TaskUsageLogger</RootNamespace>
<AssemblyName>TaskUsageLogger</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup Condition="'$(NetCoreBuild)' != 'true'">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />

Просмотреть файл

@ -9,13 +9,14 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Build.Logging.StructuredLogger</RootNamespace>
<AssemblyName>XmlFileLogger</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<ItemGroup>
<Reference Include="Microsoft.Build, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />

Просмотреть файл

@ -1,7 +1,13 @@
@echo off
setlocal
set MSBUILD_ARGS="%~dp0build.proj" /m /verbosity:minimal /fileloggerparameters:Verbosity=diag;LogFile="%~dp0msbuild.log" %*
if not defined MSBUILDLOGPATH (
set MSBUILDLOGPATH=%~dp0msbuild.log
)
set MSBUILD_ARGS="%~dp0build.proj" /m /verbosity:minimal /fileloggerparameters:Verbosity=diag;LogFile="%MSBUILDLOGPATH%" %*
:: Check for a custom MSBuild path. If not defined, default to the one in your path.
if not defined MSBUILD_CUSTOM_PATH (
@ -24,6 +30,7 @@ if not defined RUNTIME_HOST (
echo ** MSBuild Path: %MSBUILD_CUSTOM_PATH%
echo ** Runtime Host Path: %RUNTIME_HOST%
echo ** MSBuild Path: %MSBUILDCUSTOMPATH%
echo ** Building all sources
:: Restore build tools
@ -36,7 +43,7 @@ set BUILDERRORLEVEL=%ERRORLEVEL%
echo.
:: Pull the build summary from the log file
findstr /ir /c:".*Warning(s)" /c:".*Error(s)" /c:"Time Elapsed.*" "%~dp0msbuild.log"
echo ** Build completed. Exit code: %BUILDERRORLEVEL%
findstr /ir /c:".*Warning(s)" /c:".*Error(s)" /c:"Time Elapsed.*" "%MSBUILDLOGPATH%"
echo ** Build completed. Log: %MSBUILDLOGPATH% Exit code: %BUILDERRORLEVEL%
exit /b %BUILDERRORLEVEL%

Просмотреть файл

@ -8,17 +8,34 @@
<Import Project="src\dir.props" />
<ItemGroup>
<Project Include="src\dirs.proj" />
<Project Include="Samples\dirs.proj" Condition="'$(BuildSamples)'!='false'" />
<ProjectWithoutConfiguration Include="src\dirs.proj" />
<ProjectWithoutConfiguration Include="Samples\dirs.proj" Condition="'$(BuildSamples)'!='false'" />
</ItemGroup>
<Import Project="dir.targets" />
<Import Project="dir.traversal.targets" />
<!-- Ensure the BuildTools package has been restored when doing a Rebuild. This needs to happen
after import dir.traversal.targets. If this isn't done, Imports will fail because the Clean
target will load all projects. -->
<Target Name="Rebuild" DependsOnTargets="_RestoreBuildToolsPackagesConfig;Clean;Build" />
<Target Name="BulkRestoreNugetPackages"
BeforeTargets="Build;BuildAllProjects"
DependsOnTargets="_RestoreBuildToolsPackagesConfig"
Condition="'$(SkipBulkRestore)' != 'true'">
<Message Importance="High" Text="Restoring NuGet packages..." />
<Exec Command="$(NugetToolPath) restore &quot;$(SourceDir)MSBuild.sln&quot;" StandardOutputImportance="Low" />
</Target>
<!-- Create Project ItemGroup (from ProjectWithoutConfiguration) with Platform metadata -->
<Target Name="MapProjectAndPlatform" BeforeTargets="BuildAllProjects">
<ItemGroup>
<Platforms Include="$(Platform)" />
<Project Include="@(ProjectWithoutConfiguration)">
<Properties>Platform=%(Platforms.Identity)</Properties>
</Project>
</ItemGroup>
<Message Text="Building Project(s): %(Project.Identity) : Configuration=$(Configuration), %(Project.Properties) " Importance="High" />
</Target>
</Project>

0
cibuild.sh Executable file → Normal file
Просмотреть файл

Просмотреть файл

@ -10,9 +10,11 @@
</PropertyGroup>
<PropertyGroup>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<!-- This is to workaround an issue with a dependent assembly (Microsoft.Build.Tasks.CodeAnalysis.dll)
copying its dependencies (which are in the GAC). -->
<DoNotCopyLocalIfInGac>true</DoNotCopyLocalIfInGac>
<TargetMSBuildToolsVersion>15.0</TargetMSBuildToolsVersion>
</PropertyGroup>
<PropertyGroup>
@ -94,6 +96,7 @@
<!-- Set default Configuration and Platform -->
<PropertyGroup>
<Platform Condition="'$(Platform)'==''">AnyCPU</Platform>
<PlatformTarget Condition="'$(PlatformTarget)'==''">$(Platform)</PlatformTarget>
<DefineConstants>$(DefineConstants);TRACE;STANDALONEBUILD</DefineConstants>
</PropertyGroup>

Просмотреть файл

@ -17,8 +17,7 @@
<Target Name="TestAllProjects">
<!-- MSBuild tests must be sequential -->
<MSBuild Targets="Test" Projects="@(Project)" Condition="'$(SerializeProjects)'=='true'" Properties="Dummy=%(Identity)"/>
<MSBuild Targets="Test" Projects="@(Project)" Condition="'$(SerializeProjects)'!='true'" BuildInParallel="false" />
<MSBuild Targets="Test" Projects="@(Project)" BuildInParallel="false" />
</Target>
<PropertyGroup>

Просмотреть файл

@ -31,6 +31,10 @@ def project = GithubProject
batchFile("call \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat\" && RebuildWithLocalMSBuild.cmd")
}
}
// Add xunit result archiving
Utilities.addXUnitDotNETResults(newJob, 'bin/**/*_TestResults.xml')
break;
case 'OSX':
newJob.with{
@ -38,6 +42,9 @@ def project = GithubProject
shell("./cibuild.sh --scope Test")
}
}
//no test archiving yet
break;
case 'Ubuntu':
newJob.with{
@ -45,15 +52,16 @@ def project = GithubProject
shell("./cibuild.sh --scope Compile")
}
}
//no test archiving yet
break;
}
Utilities.setMachineAffinity(newJob, osName)
Utilities.setMachineAffinity(newJob, osName, 'latest-or-auto')
Utilities.standardJobSetup(newJob, project, isPR, branch)
// Add xunit result archiving
Utilities.addXUnitDotNETResults(newJob, 'bin/**/*_TestResults.xml')
// Add archiving of logs
Utilities.addArchival(newJob, 'msbuild.log')
Utilities.addArchival(newJob, 'msbuild*.log')
// Add trigger
if (isPR) {
Utilities.addGithubPRTrigger(newJob, "${osName} Build")
@ -62,4 +70,4 @@ def project = GithubProject
}
}
}
}

Просмотреть файл

@ -55,13 +55,14 @@
ForceTouch="true" />
<!-- Restore tools from packages/project.json -->
<Exec Condition="Exists('$(NuGetProjectJsonFile)')"
Command="$(DnuCoreRestoreCommand) --packages $(ToolPackagesDir) &quot;$(NuGetProjectJsonFile)&quot;"/>
<!-- <Exec Condition="Exists('$(NuGetProjectJsonFile)')"
Command="$(DotnetToolCommand) publish -f dnxcore50 -r $(NuGetRuntimeIdentifier) -o $(ToolPackagesDir) &quot;$(NuGetProjectJsonFile)&quot;"
WorkingDirectory="$(NuGetConfigDir)" /> -->
<Error Condition="'$(ErrorIfBuildToolsRestoredFromIndividualProject)'=='true'"
Text="The build tools package was just restored and so we cannot continue the build of an individual project because targets from the build tools package were not able to be imported. Please retry the build the individual project again." />

Просмотреть файл

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.DotNet.BuildTools" version="1.0.25-prerelease-00199" />
<package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net451" userInstalled="true" />
<package id="MicroBuild.Core" version="0.2.0" />
<package id="Nerdbank.GitVersioning" version="1.4.19" />
<package id="xunit.runner.console" version="2.1.0" />
<package id="NuSpec.ReferenceGenerator" version="1.3.1" />
</packages>

Просмотреть файл

@ -1,6 +1,7 @@
{
"dependencies": {
"xunit.runner.console": "2.1.0",
"Nerdbank.GitVersioning": "1.4.19",
"NuSpec.ReferenceGenerator": "1.3.1",
"Microsoft.Net.Compilers" : "1.2.0-beta1-20160108-01",
"MicroBuild.Core" : "0.2.0"

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))" />
-->
<Import Project="..\dir.props" />
<PropertyGroup>
<ProjectGuid>{571F09DB-A81A-4444-945C-6F7B530054CD}</ProjectGuid>
@ -12,14 +9,14 @@
<AssemblyName>Microsoft.Build.Framework</AssemblyName>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Include="AssemblyInfo.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
@ -176,8 +173,5 @@
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,7 @@
[$RootKey$\RuntimeConfiguration\dependentAssembly\bindingRedirection\{604B5E67-4DE2-41A7-AA00-AC65BE513FED}]
"name"="Microsoft.Build.Framework"
"codeBase"="$BaseInstallDir$\MSBuild\15.0\Bin\Microsoft.Build.Framework.dll"
"publicKeyToken"="b03f5f7f11d50a3a"
"culture"="neutral"
"oldVersion"="0.0.0.0-99.9.9.9"
"newVersion"="15.1.0.0"

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.props"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -14,14 +11,14 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Include="..\..\Shared\FxCopExclusions\Microsoft.Build.Shared.Suppressions.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Shared
/// The most current Visual Studio Version known to this version of MSBuild.
/// </summary>
#if STANDALONEBUILD
internal const string CurrentVisualStudioVersion = "14.1";
internal const string CurrentVisualStudioVersion = "15.0";
#else
internal const string CurrentVisualStudioVersion = Microsoft.VisualStudio.Internal.BrandNames.VSGeneralVersion;
#endif
@ -39,7 +39,7 @@ namespace Microsoft.Build.Shared
/// The most current VSGeneralAssemblyVersion known to this version of MSBuild.
/// </summary>
#if STANDALONEBUILD
internal const string CurrentAssemblyVersion = "14.1.0.0";
internal const string CurrentAssemblyVersion = "15.1.0.0";
#else
internal const string CurrentAssemblyVersion = Microsoft.VisualStudio.Internal.BrandNames.VSGeneralAssemblyVersion;
#endif
@ -52,7 +52,7 @@ namespace Microsoft.Build.Shared
get
{
#if STANDALONEBUILD
return "14.1";
return "15.0";
#else
Version thisAssemblyVersion = new Version(ThisAssembly.Version);
// "12.0.0.0" --> "12.0"

Просмотреть файл

@ -25,16 +25,33 @@ namespace Microsoft.Build.Shared
{
// A list of possible test runners. If the program running has one of these substrings in the name, we assume
// this is a test harness.
private static readonly string[] s_testRunners = { "XUNIT",
"NUNIT", "DEVENV", "MSTEST", "VSTEST", "TASKRUNNER", "VSTESTHOST",
"QTAGENT32", "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST"
};
private static readonly string[] s_testRunners =
{
"XUNIT", "NUNIT", "MSTEST", "VSTEST", "TASKRUNNER",
"VSTESTHOST", "QTAGENT32", "CONCURRENT", "RESHARPER", "MDHOST", "TE.PROCESSHOST"
};
/// <summary>
/// Name of the Visual Studio process(es)
/// </summary>
private static readonly string[] s_visualStudioProcess = {"DEVENV"};
/// <summary>
/// Name of the MSBuild process(es)
/// </summary>
private static readonly string[] s_msBuildProcess = {"MSBUILD"};
// This flag, when set, indicates that we are running tests. Initially assume it's true. It also implies that
// the currentExecutableOverride is set to a path (that is non-null). Assume this is not initialized when we
// have the impossible combination of runningTests = false and currentExecutableOverride = null.
private static bool s_runningTests = true;
/// <summary>
/// Set to true/false when we know whether or not we're running inside Visual Studio
/// </summary>
private static bool? s_runningInVisualStudio;
// This is the fake current executable we use in case we are running tests.
private static string s_currentExecutableOverride = null;
@ -48,30 +65,29 @@ namespace Microsoft.Build.Shared
internal static string cacheDirectory = null;
/// <summary>
/// Check if we are running unit tests (under some kind of test runner). If so, set the flag and come up with a
/// (potentially) fake executable path. Generally, the path will be used to find the config file, but also to
/// start msbuild.exe for remote nodes.
/// Check if we are running unit tests (under some kind of test runner) or in Visual Studio. If so, set the
/// flag and come up with a (potentially) fake executable path. Generally, the path will be used to find
/// the config file, but also to start msbuild.exe for remote nodes.
/// </summary>
private static void GetTestExecutionInfo()
private static void GetExecutionInfo()
{
// Get the executable we are running
var program = Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0]);
var processNameCommandLine = Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0]);
var processNameCurrentProcess = Process.GetCurrentProcess().ProcessName;
// Check if it matches the pattern
s_runningTests = program != null
&& s_testRunners.Any(
s => program.IndexOf(s, StringComparison.OrdinalIgnoreCase) == -1);
// Check if our current process name is in the list of own test runners
s_runningTests = IsProcessInList(processNameCommandLine, s_testRunners) ||
IsProcessInList(processNameCurrentProcess, s_testRunners);
// Does not look like it's a test, but check the process name
if (!s_runningTests)
{
program = Process.GetCurrentProcess().ProcessName;
s_runningTests =
s_testRunners.Any(s => program.IndexOf(s, StringComparison.OrdinalIgnoreCase) == -1);
}
// Check to see if we're running inside of Visual Studio
s_runningInVisualStudio = IsProcessInList(processNameCommandLine, s_visualStudioProcess) ||
IsProcessInList(processNameCurrentProcess, s_visualStudioProcess);
// Definitely not a test, leave
if (!s_runningTests)
bool runningInMsBuildExe = IsProcessInList(processNameCommandLine, s_msBuildProcess) ||
IsProcessInList(processNameCurrentProcess, s_msBuildProcess);
// No need to customize execution info if we're running in msbuild.exe
if (runningInMsBuildExe)
{
s_currentExecutableOverride = null;
return;
@ -106,6 +122,17 @@ namespace Microsoft.Build.Shared
}
}
/// <summary>
/// Returns true if processName appears in the processList
/// </summary>
/// <param name="processName">Name of the process</param>
/// <param name="processList">List of processes to check</param>
/// <returns></returns>
private static bool IsProcessInList(string processName, string[] processList)
{
return processList.Any(s => processName?.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0);
}
/// <summary>
/// FOR UNIT TESTS ONLY
/// Clear out the static variable used for the cache directory so that tests that
@ -1063,7 +1090,7 @@ namespace Microsoft.Build.Shared
// Check if initialized and do so if not yet
if (s_runningTests && s_currentExecutableOverride == null)
{
GetTestExecutionInfo();
GetExecutionInfo();
}
return s_runningTests;
}
@ -1080,12 +1107,28 @@ namespace Microsoft.Build.Shared
// Check if initialized and do so if not yet
if (s_runningTests && s_currentExecutableOverride == null)
{
GetTestExecutionInfo();
GetExecutionInfo();
}
return s_currentExecutableOverride;
}
}
/// <summary>
/// Returns true when the entry point application is Visual Studio.
/// </summary>
internal static bool RunningInVisualStudio
{
get
{
// Check if initialized and do so if not yet
if (!s_runningInVisualStudio.HasValue)
{
GetExecutionInfo();
}
return s_runningInVisualStudio.Value;
}
}
internal static StreamWriter OpenWrite(string path, bool append, Encoding encoding = null)
{
const int DefaultFileStreamBufferSize = 4096;

Просмотреть файл

@ -68,9 +68,10 @@ namespace Microsoft.Build.Shared
internal static readonly Version visualStudioVersion110 = new Version(11, 0);
internal static readonly Version visualStudioVersion120 = new Version(12, 0);
internal static readonly Version visualStudioVersion140 = new Version(14, 0);
internal static readonly Version visualStudioVersion150 = new Version(15, 0);
// keep this up-to-date; always point to the latest visual studio version.
internal static readonly Version visualStudioVersionLatest = visualStudioVersion140;
internal static readonly Version visualStudioVersionLatest = visualStudioVersion150;
private const string dotNetFrameworkRegistryPath = "SOFTWARE\\Microsoft\\.NETFramework";
private const string dotNetFrameworkSetupRegistryPath = "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP";
@ -259,6 +260,19 @@ namespace Microsoft.Build.Shared
dotNetFrameworkVersion46,
dotNetFrameworkVersion461
}),
// VS15
new VisualStudioSpec(visualStudioVersion150, "NETFXSDK\\{0}", "v8.1", "InstallationFolder", new []
{
dotNetFrameworkVersion11,
dotNetFrameworkVersion20,
dotNetFrameworkVersion35,
dotNetFrameworkVersion40,
dotNetFrameworkVersion45,
dotNetFrameworkVersion451,
dotNetFrameworkVersion46,
dotNetFrameworkVersion461,
}),
};
/// <summary>
@ -279,7 +293,12 @@ namespace Microsoft.Build.Shared
{ Tuple.Create(dotNetFrameworkVersion451, visualStudioVersion140), Tuple.Create(dotNetFrameworkVersion45, visualStudioVersion140) },
{ Tuple.Create(dotNetFrameworkVersion46, visualStudioVersion140), Tuple.Create(dotNetFrameworkVersion451, visualStudioVersion140) },
{ Tuple.Create(dotNetFrameworkVersion461, visualStudioVersion140), Tuple.Create(dotNetFrameworkVersion46, visualStudioVersion140) },
};
// VS15
{ Tuple.Create(dotNetFrameworkVersion451, visualStudioVersion150), Tuple.Create(dotNetFrameworkVersion45, visualStudioVersion150) },
{ Tuple.Create(dotNetFrameworkVersion46, visualStudioVersion150), Tuple.Create(dotNetFrameworkVersion451, visualStudioVersion150) },
{ Tuple.Create(dotNetFrameworkVersion461, visualStudioVersion150), Tuple.Create(dotNetFrameworkVersion46, visualStudioVersion150) },
};
private static readonly IReadOnlyDictionary<Version, DotNetFrameworkSpec> s_dotNetFrameworkSpecDict;
private static readonly IReadOnlyDictionary<Version, VisualStudioSpec> s_visualStudioSpecDict;

Просмотреть файл

@ -297,6 +297,13 @@ namespace Microsoft.Build.BackEnd
where D : IDictionary<string, T>
where T : class, INodePacketTranslatable;
/// <summary>
/// Translates a dictionary of type { string, List {string} }
/// </summary>
/// <param name="dictionary">The dictionary to be translated.</param>
/// <param name="comparer">The comparer used to instantiate the dictionary.</param>
void TranslateDictionaryList(ref Dictionary<string, List<string>> dictionary, IEqualityComparer<string> comparer);
/// <summary>
/// Translates the boolean that says whether this value is null or not
/// </summary>

Просмотреть файл

@ -500,6 +500,32 @@ namespace Microsoft.Build.BackEnd
}
}
/// <summary>
/// Translates a dictionary of type { string, List {string} }
/// </summary>
/// <param name="dictionary">The dictionary to be translated.</param>
/// <param name="comparer">The comparer used to instantiate the dictionary.</param>
public void TranslateDictionaryList(ref Dictionary<string, List<string>> dictionary, IEqualityComparer<string> comparer)
{
if (!TranslateNullable(dictionary))
{
return;
}
int count = _reader.ReadInt32();
dictionary = new Dictionary<string, List<string>>(count, comparer);
for (int i = 0; i < count; i++)
{
string key = null;
Translate(ref key);
List<string> value = null;
Translate(ref value);
dictionary[key] = value;
}
}
/// <summary>
/// Translates a dictionary of { string, T } for dictionaries with public parameterless constructors.
/// </summary>
@ -1000,6 +1026,30 @@ namespace Microsoft.Build.BackEnd
}
}
/// <summary>
/// Translates a dictionary of type { string, List {string} }
/// </summary>
/// <param name="dictionary">The dictionary to be translated.</param>
/// <param name="comparer">The comparer used to instantiate the dictionary.</param>
public void TranslateDictionaryList(ref Dictionary<string, List<string>> dictionary, IEqualityComparer<string> comparer)
{
if (!TranslateNullable(dictionary))
{
return;
}
int count = dictionary.Count;
_writer.Write(count);
foreach (KeyValuePair<string, List<string>> pair in dictionary)
{
string key = pair.Key;
Translate(ref key);
List<string> value = pair.Value;
Translate(ref value);
}
}
/// <summary>
/// Translates a dictionary of { string, T } for dictionaries with public parameterless constructors.
/// </summary>

Просмотреть файл

@ -96,11 +96,8 @@ namespace Microsoft.Build.Evaluation
try
{
result =
(
File.Exists(FileUtilities.CurrentExecutableConfigurationFilePath) &&
File.ReadAllText(FileUtilities.CurrentExecutableConfigurationFilePath).Contains("toolsVersion")
);
var configFile = FileUtilities.CurrentExecutableConfigurationFilePath;
result = File.Exists(configFile) && File.ReadAllText(configFile).Contains("toolsVersion");
}
catch (Exception e)
{
@ -157,14 +154,14 @@ namespace Microsoft.Build.Evaluation
}
/// <summary>
/// Collection of all the search paths for MSBuildExtensionsPath*, per OS
/// Collection of all the search paths for project imports, per OS
/// </summary>
[ConfigurationProperty("msbuildExtensionsPathSearchPaths")]
public ExtensionsPathsElementCollection AllMSBuildExtensionPathsSearchPaths
[ConfigurationProperty("projectImportSearchPaths")]
public ExtensionsPathsElementCollection AllProjectImportSearchPaths
{
get
{
return (ExtensionsPathsElementCollection)base["msbuildExtensionsPathSearchPaths"];
return (ExtensionsPathsElementCollection)base["projectImportSearchPaths"];
}
}

Просмотреть файл

@ -1,8 +1,7 @@
<?xml version ="1.0"?>
<configuration>
<configSections>
<!-- Microsoft.Build.Engine instead of Microsoft.Build here because a task run under Microsoft.Build may load Microsoft.Build.Engine, which will attempt to read this section. -->
<section name="msbuildToolsets" type="Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build, Version=14.1.0.0, Culture=neutral" />
<section name="msbuildToolsets" type="Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
@ -13,29 +12,29 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Conversion.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Tasks.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Utilities.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<!-- To define one or more new toolsets, add an 'msbuildToolsets' element in this file. -->
<msbuildToolsets default="14.1">
<toolset toolsVersion="14.1">
<msbuildToolsets default="15.0">
<toolset toolsVersion="15.0">
<property name="MSBuildToolsPath" value="."/>
</toolset>
<toolset toolsVersion="12.0">

Просмотреть файл

@ -0,0 +1,7 @@
[$RootKey$\RuntimeConfiguration\dependentAssembly\bindingRedirection\{CCA70AFE-5E92-4B5E-940D-FAE11D564E72}]
"name"="Microsoft.Build.Utilities.Core"
"codeBase"="$BaseInstallDir$\MSBuild\15.0\Bin\Microsoft.Build.Utilities.Core.dll"
"publicKeyToken"="b03f5f7f11d50a3a"
"culture"="neutral"
"oldVersion"="0.0.0.0-99.9.9.9"
"newVersion"="15.1.0.0"

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.props"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -15,14 +12,14 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup >
<Compile Condition="'$(NetCoreBuild)' == 'true'" Include="..\Shared\Compat\SafeHandleZeroOrMinusOneIsInvalid.cs">
<Link>Compat\SafeHandleZeroOrMinusOneIsInvalid.cs</Link>

Просмотреть файл

@ -145,31 +145,31 @@ namespace Microsoft.Build.Utilities
}
}
DependentPlatforms = new List<DependentPlatform>();
ApiContracts = new List<ApiContract>();
if (rootElement != null)
{
Name = rootElement.GetAttribute(Attributes.Name);
FriendlyName = rootElement.GetAttribute(Attributes.FriendlyName);
PlatformVersion = rootElement.GetAttribute(Attributes.Version);
}
DependentPlatforms = new List<DependentPlatform>();
ApiContracts = new List<ApiContract>();
foreach (XmlNode childNode in rootElement.ChildNodes)
{
XmlElement childElement = childNode as XmlElement;
if (childElement == null)
{
continue;
}
foreach (XmlNode childNode in rootElement.ChildNodes)
{
XmlElement childElement = childNode as XmlElement;
if (childElement == null)
{
continue;
}
if (ApiContract.IsContainedApiContractsElement(childElement.Name))
{
ApiContract.ReadContractsElement(childElement, ApiContracts);
}
else if (String.Equals(childElement.Name, Elements.DependentPlatform, StringComparison.Ordinal))
{
DependentPlatforms.Add(new DependentPlatform(childElement.GetAttribute(Attributes.Name), childElement.GetAttribute(Attributes.Version)));
if (ApiContract.IsContainedApiContractsElement(childElement.Name))
{
ApiContract.ReadContractsElement(childElement, ApiContracts);
}
else if (String.Equals(childElement.Name, Elements.DependentPlatform, StringComparison.Ordinal))
{
DependentPlatforms.Add(new DependentPlatform(childElement.GetAttribute(Attributes.Name), childElement.GetAttribute(Attributes.Version)));
}
}
}
}

Просмотреть файл

@ -103,11 +103,16 @@ namespace Microsoft.Build.Utilities
/// </summary>
Version140,
/// <summary>
/// Visual Studio Dev15
/// </summary>
Version150,
// keep this up-to-date; always point to the last entry.
/// <summary>
/// The latest version available at the time of release
/// </summary>
VersionLatest = Version140
VersionLatest = Version150
}
/// <summary>
@ -856,30 +861,33 @@ namespace Microsoft.Build.Utilities
string registryRoot
)
{
if (s_cachedTargetPlatformReferences == null)
lock (s_locker)
{
s_cachedTargetPlatformReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
if (s_cachedTargetPlatformReferences == null)
{
s_cachedTargetPlatformReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
string cacheKey = String.Join("|", sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
string cacheKey = String.Join("|", sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
string[] targetPlatformReferences = null;
if (s_cachedTargetPlatformReferences.TryGetValue(cacheKey, out targetPlatformReferences))
{
string[] targetPlatformReferences = null;
if (s_cachedTargetPlatformReferences.TryGetValue(cacheKey, out targetPlatformReferences))
{
return targetPlatformReferences;
}
if (String.IsNullOrEmpty(sdkIdentifier) && String.IsNullOrEmpty(sdkVersion))
{
targetPlatformReferences = GetLegacyTargetPlatformReferences(targetPlatformIdentifier, targetPlatformVersion, diskRoots, registryRoot);
}
else
{
targetPlatformReferences = GetTargetPlatformReferencesFromManifest(sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
}
s_cachedTargetPlatformReferences.Add(cacheKey, targetPlatformReferences);
return targetPlatformReferences;
}
if (String.IsNullOrEmpty(sdkIdentifier) && String.IsNullOrEmpty(sdkVersion))
{
targetPlatformReferences = GetLegacyTargetPlatformReferences(targetPlatformIdentifier, targetPlatformVersion, diskRoots, registryRoot);
}
else
{
targetPlatformReferences = GetTargetPlatformReferencesFromManifest(sdkIdentifier, sdkVersion, targetPlatformIdentifier, targetPlatformMinVersion, targetPlatformVersion, diskRoots, registryRoot);
}
s_cachedTargetPlatformReferences.Add(cacheKey, targetPlatformReferences);
return targetPlatformReferences;
}
/// <summary>
@ -901,53 +909,57 @@ namespace Microsoft.Build.Utilities
string registryRoot
)
{
if (s_cachedExtensionSdkReferences == null)
lock (s_locker)
{
s_cachedExtensionSdkReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
string cacheKey = String.Join("|", extensionSdkMoniker, targetSdkIdentifier, targetSdkVersion);
string[] extensionSdkReferences = null;
if (s_cachedExtensionSdkReferences.TryGetValue(cacheKey, out extensionSdkReferences))
{
return extensionSdkReferences;
}
TargetPlatformSDK matchingSdk = GetMatchingPlatformSDK(targetSdkIdentifier, targetSdkVersion, diskRoots, extensionDiskRoots, registryRoot);
if (matchingSdk == null)
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find root SDK for SDKI = '{0}', SDKV = '{1}'", targetSdkIdentifier, targetSdkVersion);
}
else
{
string targetSdkPath = matchingSdk.Path;
string extensionSdkPath = null;
if (matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out extensionSdkPath)
||
(
// It is possible the SDK may be of the newer style (targets multiple). We need to hit the untargeted SDK cache to look for a hit.
s_cachedExtensionSdks.TryGetValue(extensionDiskRoots, out matchingSdk)
&& matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out extensionSdkPath)
))
if (s_cachedExtensionSdkReferences == null)
{
ExtensionSDK extensionSdk = new ExtensionSDK(extensionSdkMoniker, extensionSdkPath);
if (extensionSdk.SDKType == SDKType.Framework || extensionSdk.SDKType == SDKType.Platform)
{
// We don't want to attempt to gather ApiContract references if the framework isn't explicitly marked as Framework/Platform
extensionSdkReferences = GetApiContractReferences(extensionSdk.ApiContracts, targetSdkPath);
}
s_cachedExtensionSdkReferences = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
}
string cacheKey = String.Join("|", extensionSdkMoniker, targetSdkIdentifier, targetSdkVersion);
string[] extensionSdkReferences = null;
if (s_cachedExtensionSdkReferences.TryGetValue(cacheKey, out extensionSdkReferences))
{
return extensionSdkReferences;
}
TargetPlatformSDK matchingSdk = GetMatchingPlatformSDK(targetSdkIdentifier, targetSdkVersion, diskRoots, extensionDiskRoots, registryRoot);
if (matchingSdk == null)
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find root SDK for SDKI = '{0}', SDKV = '{1}'", targetSdkIdentifier, targetSdkVersion);
}
else
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find matching extension SDK = '{0}'", extensionSdkMoniker);
}
}
string targetSdkPath = matchingSdk.Path;
string extensionSdkPath = null;
s_cachedExtensionSdkReferences.Add(cacheKey, extensionSdkReferences);
return extensionSdkReferences;
if (matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out extensionSdkPath)
||
(
// It is possible the SDK may be of the newer style (targets multiple). We need to hit the untargeted SDK cache to look for a hit.
s_cachedExtensionSdks.TryGetValue(extensionDiskRoots, out matchingSdk)
&& matchingSdk.ExtensionSDKs.TryGetValue(extensionSdkMoniker, out extensionSdkPath)
))
{
ExtensionSDK extensionSdk = new ExtensionSDK(extensionSdkMoniker, extensionSdkPath);
if (extensionSdk.SDKType == SDKType.Framework || extensionSdk.SDKType == SDKType.Platform)
{
// We don't want to attempt to gather ApiContract references if the framework isn't explicitly marked as Framework/Platform
extensionSdkReferences = GetApiContractReferences(extensionSdk.ApiContracts, targetSdkPath);
}
}
else
{
ErrorUtilities.DebugTraceMessage("GetExtensionSdkReferences", "Could not find matching extension SDK = '{0}'", extensionSdkMoniker);
}
}
s_cachedExtensionSdkReferences.Add(cacheKey, extensionSdkReferences);
return extensionSdkReferences;
}
}
/// <summary>
@ -1797,6 +1809,9 @@ namespace Microsoft.Build.Utilities
case VisualStudioVersion.Version140:
return FrameworkLocationHelper.visualStudioVersion140;
case VisualStudioVersion.Version150:
return FrameworkLocationHelper.visualStudioVersion150;
default:
ErrorUtilities.ThrowArgument("ToolLocationHelper.UnsupportedVisualStudioVersion", version);
return null;

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.props"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -14,14 +11,14 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Include="..\..\Shared\FxCopExclusions\Microsoft.Build.Shared.Suppressions.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
@ -93,8 +90,5 @@
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.targets"/>
</Project>

Просмотреть файл

@ -1860,65 +1860,82 @@ class X
public void LaunchMultipleOfSameTool_SameCommand()
{
string testDir = Path.Combine(Path.GetTempPath(), "LaunchMultipleOfSameTool_SameCommand");
Directory.CreateDirectory(testDir);
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
try
{
Directory.CreateDirectory(testDir);
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i baz " + tempFilePath, 3));
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications = new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i baz " + tempFilePath, 3));
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 3));
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications = new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, createTestDirectory: false);
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 3));
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, createTestDirectory: false);
}
finally
{
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
}
}
[Fact]
public void LaunchMultipleOfSameTool_DifferentCommands1()
{
string testDir = Path.Combine(Path.GetTempPath(), "LaunchMultipleOfSameTool_DifferentCommands1");
Directory.CreateDirectory(testDir);
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
try
{
Directory.CreateDirectory(testDir);
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i foo " + tempFilePath, 3));
toolsToLaunch.Add(new Tuple<string, string, int>(null, "\"" + destinationFindstrPath + "\" /i baz " + tempFilePath, 3));
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i foo " + tempFilePath, 3));
toolsToLaunch.Add(new Tuple<string, string, int>(null, "\"" + destinationFindstrPath + "\" /i baz " + tempFilePath, 3));
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications = new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications = new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 6));
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 6));
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, createTestDirectory: false);
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, createTestDirectory: false);
}
finally
{
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
}
}
[Fact]
@ -2133,34 +2150,44 @@ class X
public void LaunchMultipleOfSameTool_DifferentContexts()
{
string testDir = Path.Combine(Path.GetTempPath(), "LaunchMultipleOfSameTool_DifferentContexts");
Directory.CreateDirectory(testDir);
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
try
{
Directory.CreateDirectory(testDir);
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
string originalFindstrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "findstr.exe");
string destinationFindstrPath = Path.Combine(testDir, "abc.exe");
File.Copy(originalFindstrPath, destinationFindstrPath);
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
string tempFilePath = Path.Combine(testDir, "bar.txt");
File.WriteAllText(tempFilePath, "foo baz");
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i baz " + tempFilePath, 3));
// Item1: appname
// Item2: command line
// Item3: number of times to launch
IList<Tuple<string, string, int>> toolsToLaunch = new List<Tuple<string, string, int>>();
toolsToLaunch.Add(new Tuple<string, string, int>(destinationFindstrPath, "/i baz " + tempFilePath, 3));
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications = new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest2", toolsToLaunch));
// Item1: FileTracker context name
// Item2: Tuple <string, string, int> as described above
IList<Tuple<string, IList<Tuple<string, string, int>>>> contextSpecifications =
new List<Tuple<string, IList<Tuple<string, string, int>>>>();
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest", toolsToLaunch));
contextSpecifications.Add(new Tuple<string, IList<Tuple<string, string, int>>>("ProcessLaunchTest2", toolsToLaunch));
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 3));
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest2-abc*tlog", 3));
// Item1: tlog pattern
// Item2: # times it's expected to appear
IList<Tuple<string, int>> tlogPatterns = new List<Tuple<string, int>>();
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest-abc*tlog", 3));
tlogPatterns.Add(new Tuple<string, int>("ProcessLaunchTest2-abc*tlog", 3));
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, false);
}
catch (Exception)
{
FileUtilities.DeleteDirectoryNoThrow(testDir, true);
}
LaunchDuplicateToolsAndVerifyTlogExistsForEach(testDir, contextSpecifications, tlogPatterns, createTestDirectory: false);
}
[Fact(Skip = "Ignored in MSTest")]

Просмотреть файл

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="dogfood" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildProjectReferences>true</BuildProjectReferences>
</PropertyGroup>
<Import Project="$(_NTDRIVE)$(_NTROOT)\tools\Microsoft.DevDiv.Settings.targets"/>
<ItemGroup>

Просмотреть файл

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="dogfood" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildProjectReferences>true</BuildProjectReferences>
</PropertyGroup>
<Import Project="$(_NTDRIVE)$(_NTROOT)\tools\Microsoft.DevDiv.Settings.targets"/>
<ItemGroup>
@ -19,4 +15,3 @@
<Import Project="$(_NTDRIVE)$(_NTROOT)\tools\Microsoft.devdiv.traversal.targets"/>
</Project>

Просмотреть файл

@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="dogfood" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(_NTDRIVE)$(_NTROOT)\tools\Microsoft.DevDiv.Settings.targets" />
<PropertyGroup Label="Dependencies">
<UsingPartitionOmni>true</UsingPartitionOmni>
<UsingProjectOmniFramework>true</UsingProjectOmniFramework>
<UsingProjectOmniMstestintegration>true</UsingProjectOmniMstestintegration>
<UsingPartitionUnitTest>true</UsingPartitionUnitTest>
<UsingProjectUnitTestUnitTestFramework>true</UsingProjectUnitTestUnitTestFramework>
</PropertyGroup>
<ImportGroup Label="Dependencies">
<Import Project="$(PartitionExports)" />
</ImportGroup>
<PropertyGroup>
<OutputPath>$(SuiteBinPath)</OutputPath>
<OutputType>library</OutputType>
@ -37,15 +47,12 @@
</ItemGroup>
<!-- Assemblies Files we depend on -->
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="Microsoft.Test.Apex.Framework" />
<Reference Include="Microsoft.Test.Apex.MSTestIntegration" />
<ProjectReference Include="..\..\Framework\Framework.csproj">
<Project>{784BF121-CE8F-4314-AA55-E86AB61670FE}</Project>
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>

Просмотреть файл

@ -972,7 +972,7 @@ namespace Microsoft.Build.Execution
_detailedSummary = true;
}
FindMSBuildExe();
_nodeExeLocation = FindMSBuildExe();
}
/// <summary>
@ -991,34 +991,22 @@ namespace Microsoft.Build.Execution
/// <summary>
/// This method determines where MSBuild.Exe is and sets the NodeExePath to that by default.
/// </summary>
private void FindMSBuildExe()
private string FindMSBuildExe()
{
string location = _nodeExeLocation;
// Use the location specified by the user in code.
if (_nodeExeLocation != null && CheckMSBuildExeExistsAt(_nodeExeLocation))
if (!string.IsNullOrEmpty(location) && CheckMSBuildExeExistsAt(location))
{
return;
return location;
}
// Use the location specified in the environment.
// MSBUILD_EXE_PATH optionally contains the full path to msbuild.exe, and if present
// overrides the rest
string path = Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH");
if (path != null && CheckMSBuildExeExistsAt(path))
{
_nodeExeLocation = path;
return;
}
// Try what we think is the current executable path.
location = FileUtilities.CurrentExecutablePath;
// Use the default location of the directory from which the engine was loaded.
#if FEATURE_APPDOMAIN
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MSBuild.exe");
#else
path = Path.GetDirectoryName(typeof(BuildParameters).GetTypeInfo().Assembly.Location);
#endif
if (path != null && CheckMSBuildExeExistsAt(path))
if (CheckMSBuildExeExistsAt(location))
{
_nodeExeLocation = path;
return;
return location;
}
// Get the location pointed to by the MSBuildToolsPath in the "current" ToolsVersion
@ -1027,58 +1015,16 @@ namespace Microsoft.Build.Execution
EnsureToolsets();
Toolset currentToolset = _toolsetProvider.GetToolset(MSBuildConstants.CurrentToolsVersion);
if (currentToolset != null)
if (currentToolset != null && !string.IsNullOrEmpty(currentToolset.ToolsPath))
{
path = Path.Combine(currentToolset.ToolsPath, "MSBuild.exe");
if (path != null && CheckMSBuildExeExistsAt(path))
location = Path.Combine(currentToolset.ToolsPath, "MSBuild.exe");
if (CheckMSBuildExeExistsAt(location))
{
_nodeExeLocation = path;
return;
return location;
}
}
#if FEATURE_APPDOMAIN
// Search in the location of any assemblies we have loaded.
foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!assembly.IsDynamic)
{
try
{
path = Path.GetDirectoryName(assembly.Location);
}
catch (Exception ex)
{
if (ExceptionHandling.IsCriticalException(ex))
{
throw;
}
// In some circumstances, assembly.Location throws NotSupportedException (ex. when
// it's an anonymous dynamic assembly -- which we're already protecting against, but
// there could be other examples we don't know of). If there's an error here, we really don't
// care -- it's just one fewer place we can look for the path to MSBuild.exe. So
// just continue.
continue;
}
if (CheckMSBuildExeExistsAt(Path.Combine(path, "MSBuild.exe")))
{
_nodeExeLocation = Path.Combine(path, "MSBuild.exe");
return;
}
}
}
#endif
// Search in the framework directory. Checks the COMPLUS_INSTALL_ROOT among other things.
path = FrameworkLocationHelper.PathToDotNetFrameworkV40;
if (path != null && CheckMSBuildExeExistsAt(Path.Combine(path, "MSBuild.exe")))
{
_nodeExeLocation = Path.Combine(path, "MSBuild.exe");
}
// Well, we just can't find it. Maybe they will only build in-proc and won't need it...
return location;
}
/// <summary>
@ -1089,7 +1035,7 @@ namespace Microsoft.Build.Execution
/// </summary>
private bool CheckMSBuildExeExistsAt(string path)
{
if (s_msbuildExeKnownToExistAt != null && String.Equals(path, s_msbuildExeKnownToExistAt, StringComparison.OrdinalIgnoreCase))
if (s_msbuildExeKnownToExistAt != null && string.Equals(path, s_msbuildExeKnownToExistAt, StringComparison.OrdinalIgnoreCase))
{
// We found it there last time: it must exist there.
return true;

Просмотреть файл

@ -116,14 +116,12 @@ namespace Microsoft.Build.BackEnd
}
// Start the new process. We pass in a node mode with a node number of 1, to indicate that we
// want to start up just a standard MSBuild out-of-proc node.
string commandLineArgs = " /nologo /nodemode:1 ";
// Disable node re-use if it is not requested (because no argument means enable reuse).
if (!ComponentHost.BuildParameters.EnableNodeReuse)
{
commandLineArgs += "/nodeReuse:false";
}
// want to start up just a standard MSBuild out-of-proc node.
// Note: We need to always pass /nodeReuse to ensure the value for /nodeReuse from msbuild.rsp
// (next to msbuild.exe) is ignored.
string commandLineArgs = ComponentHost.BuildParameters.EnableNodeReuse ?
"/nologo /nodemode:1 /nodeReuse:true" :
"/nologo /nodemode:1 /nodeReuse:false";
// Make it here.
CommunicationsUtilities.Trace("Starting to acquire a new or existing node to establish node ID {0}...", nodeId);

Просмотреть файл

@ -73,7 +73,7 @@ namespace Microsoft.Build.BackEnd
/// This class represents a single target in the TargetBuilder. It maintains the state machine for a particular target as well as
/// relevant information on outputs generated while a target is running.
/// </summary>
[DebuggerDisplay("Name={targetSpecification.TargetName} State={state} Result={targetResult.ResultCode}")]
[DebuggerDisplay("Name={_targetSpecification.TargetName} State={_state} Result={_targetResult.ResultCode}")]
internal class TargetEntry : IEquatable<TargetEntry>
{
/// <summary>

Просмотреть файл

@ -49,7 +49,7 @@ namespace Microsoft.Build.Collections
{
/// <summary>
/// Implementation notes:
/// This uses an array-based implementation similar to <see cref="Dictionary{T}" />, using a buckets array
/// This uses an array-based implementation similar to <see cref="T:Dictionary{T}" />, using a buckets array
/// to map hash values to the Slots array. Items in the Slots array that hash to the same value
/// are chained together through the "next" indices.
///

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Construction
/// <summary>
/// ProjectUsingTaskElement represents the Import element in the MSBuild project.
/// </summary>
[DebuggerDisplay("ExecuteTargets={ExecuteTargets}")]
[DebuggerDisplay("ExecuteTargetsAttribute={ExecuteTargetsAttribute}")]
public class ProjectOnErrorElement : ProjectElement
{
/// <summary>

Просмотреть файл

@ -19,7 +19,7 @@ namespace Microsoft.Build.Construction
/// <summary>
/// ProjectOutputElement represents the Output element in the MSBuild project.
/// </summary>
[DebuggerDisplay("Name={Name} TaskParameter={TaskParameter} ItemName={ItemName} PropertyName={PropertyName} Condition={Condition}")]
[DebuggerDisplay("TaskParameter={TaskParameter} ItemType={ItemType} PropertyName={PropertyName} Condition={Condition}")]
public class ProjectOutputElement : ProjectElement
{
/// <summary>

Просмотреть файл

@ -1144,7 +1144,7 @@ namespace Microsoft.Build.Construction
ProjectTargetInstance target = metaprojectInstance.AddTarget(targetName ?? "Build", String.Empty, String.Empty, outputItemAsItem, null, String.Empty, String.Empty, false /* legacy target returns behaviour */);
AddReferencesBuildTask(metaprojectInstance, target, targetName, outputItem);
AddReferencesBuildTask(metaprojectInstance, target, targetName, null /* No need to capture output */);
// Add the task to build the actual project.
AddProjectBuildTask(traversalProject, project, projectConfiguration, target, targetName, EscapingUtilities.Escape(project.AbsolutePath), String.Empty, outputItem);
@ -1209,7 +1209,7 @@ namespace Microsoft.Build.Construction
ProjectTargetInstance newTarget = metaprojectInstance.AddTarget(targetName ?? "Build", ComputeTargetConditionForWebProject(project), null, null, null, null, "GetFrameworkPathAndRedistList", false /* legacy target returns behaviour */);
// Build the references
AddReferencesBuildTask(metaprojectInstance, newTarget, targetName, null);
AddReferencesBuildTask(metaprojectInstance, newTarget, targetName, null /* No need to capture output */);
if (targetName == "Clean")
{

Просмотреть файл

@ -72,7 +72,7 @@ namespace Microsoft.Build.Evaluation
/// <remarks>
/// UNDONE: (Multiple configurations.) Protect against problems when attempting to edit, after edits were made to the same ProjectRootElement either directly or through other projects evaluated from that ProjectRootElement.
/// </remarks>
[DebuggerDisplay("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties={data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes={data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items={data.Items.Count} #Targets={data.Targets.Count}")]
[DebuggerDisplay("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties={_data._globalProperties.Count} #Properties={_data.Properties.Count} #ItemTypes={_data.ItemTypes.Count} #ItemDefinitions={_data.ItemDefinitions.Count} #Items={_data.Items.Count} #Targets={_data.Targets.Count}")]
public class Project
{
/// <summary>

Просмотреть файл

@ -384,7 +384,7 @@ namespace Microsoft.Build.Evaluation
/// Gets the file version of the file in which the Engine assembly lies.
/// </summary>
/// <remarks>
/// This is the Windows file version (specifically the value of the ProductVersion
/// This is the Windows file version (specifically the value of the FileVersion
/// resource), not necessarily the assembly version.
/// If you want the assembly version, use Constants.AssemblyVersion.
/// This is not the <see cref="ToolsetsVersion">ToolsetCollectionVersion</see>.
@ -400,7 +400,7 @@ namespace Microsoft.Build.Evaluation
// work when Microsoft.Build.dll has been shadow-copied, for example
// in scenarios where NUnit is loading Microsoft.Build.
var versionInfo = FileVersionInfo.GetVersionInfo(FileUtilities.ExecutingAssemblyPath);
s_engineVersion = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart);
s_engineVersion = new Version(versionInfo.FileMajorPart, versionInfo.FileMinorPart, versionInfo.FileBuildPart, versionInfo.FilePrivatePart);
}
return s_engineVersion;

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
namespace Microsoft.Build.Evaluation
{
/// <summary>
/// Struct representing a reference to a project import path with property fall-back
/// </summary>
internal struct ProjectImportPathMatch
{
/// <summary>
/// ProjectImportPathMatch instance representing no fall-back
/// </summary>
public static readonly ProjectImportPathMatch None = new ProjectImportPathMatch(string.Empty, new List<string>());
internal ProjectImportPathMatch(string propertyName, IEnumerable<string> searchPaths)
{
PropertyName = propertyName;
SearchPaths = searchPaths;
MsBuildPropertyFormat = $"$({PropertyName})";
}
/// <summary>
/// String representation of the property reference - eg. "MSBuildExtensionsPath32"
/// </summary>
public string PropertyName { get; }
/// <summary>
/// Returns the corresponding property name - eg. "$(MSBuildExtensionsPath32)"
/// </summary>
public string MsBuildPropertyFormat { get; }
/// <summary>
/// Enumeration of the search paths for the property.
/// </summary>
public IEnumerable<string> SearchPaths { get; }
}
}

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.Build.Evaluation
/// often will not point to a single ProjectItemDefinitionElement. The metadata within, however, will each point to a single
/// ProjectMetadataElement, and these can be added, removed, and modified.
/// </remarks>
[DebuggerDisplay("{itemType} #Metadata={MetadataCount}")]
[DebuggerDisplay("{_itemType} #Metadata={MetadataCount}")]
public class ProjectItemDefinition : IKeyed, IMetadataTable, IItemDefinition<ProjectMetadata>, IProjectMetadataParent
{
/// <summary>

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Build.Evaluation
/// <remarks>
/// Never used to represent built-in metadata, like %(Filename). There is always a backing XML object.
/// </remarks>
[DebuggerDisplay("{Name}={EvaluatedValue} [{xml.Value}]")]
[DebuggerDisplay("{Name}={EvaluatedValue} [{_xml.Value}]")]
public class ProjectMetadata : IKeyed, IValued, IEquatable<ProjectMetadata>, IMetadatum
{
/// <summary>

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Aggregation of a set of properties that correspond to a particular sub-toolset.
/// </summary>
[DebuggerDisplay("SubToolsetVersion={SubToolsetVersion} #Properties={properties.Count}")]
[DebuggerDisplay("SubToolsetVersion={SubToolsetVersion} #Properties={_properties.Count}")]
public class SubToolset : INodePacketTranslatable
{
/// <summary>

Просмотреть файл

@ -41,7 +41,7 @@ namespace Microsoft.Build.Evaluation
/// <remarks>
/// UNDONE: Review immutability. If this is not immutable, add a mechanism to notify the project collection/s owning it to increment their toolsetVersion.
/// </remarks>
[DebuggerDisplay("ToolsVersion={ToolsVersion} ToolsPath={ToolsPath} #Properties={properties.Count}")]
[DebuggerDisplay("ToolsVersion={ToolsVersion} ToolsPath={ToolsPath} #Properties={_properties.Count}")]
public class Toolset : INodePacketTranslatable
{
/// <summary>
@ -175,7 +175,7 @@ namespace Microsoft.Build.Evaluation
private DirectoryGetFiles _getFiles;
/// <summary>
/// Delegate to check to see if a direcotry exists
/// Delegate to check to see if a directory exists
/// </summary>
private DirectoryExists _directoryExists = null;
@ -205,6 +205,11 @@ namespace Microsoft.Build.Evaluation
/// </summary>
private string _defaultSubToolsetVersion;
/// <summary>
/// Map of project import properties to their list of fall-back search paths
/// </summary>
private Dictionary<string, List<string>> _propertySearchPathsTable;
/// <summary>
/// Constructor taking only tools version and a matching tools path
/// </summary>
@ -274,6 +279,7 @@ namespace Microsoft.Build.Evaluation
_environmentProperties = environmentProperties;
_overrideTasksPath = msbuildOverrideTasksPath;
_defaultOverrideToolsVersion = defaultOverrideToolsVersion;
}
/// <summary>
@ -285,33 +291,25 @@ namespace Microsoft.Build.Evaluation
/// Properties that should be associated with the Toolset.
/// May be null, in which case an empty property group will be used.
/// </param>
internal Toolset(string toolsVersion, string toolsPath, PropertyDictionary<ProjectPropertyInstance> buildProperties, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, IDictionary<string, SubToolset> subToolsets, string msbuildOverrideTasksPath, string defaultOverrideToolsVersion)
internal Toolset(string toolsVersion, string toolsPath, PropertyDictionary<ProjectPropertyInstance> buildProperties, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, IDictionary<string, SubToolset> subToolsets, string msbuildOverrideTasksPath, string defaultOverrideToolsVersion, Dictionary<string, List<string>> importSearchPathsTable = null)
: this(toolsVersion, toolsPath, environmentProperties, globalProperties, msbuildOverrideTasksPath, defaultOverrideToolsVersion)
{
if (_properties == null)
{
if (null != buildProperties)
{
_properties = new PropertyDictionary<ProjectPropertyInstance>(buildProperties);
}
else
{
_properties = new PropertyDictionary<ProjectPropertyInstance>();
}
_properties = buildProperties != null
? new PropertyDictionary<ProjectPropertyInstance>(buildProperties)
: new PropertyDictionary<ProjectPropertyInstance>();
}
if (subToolsets != null)
{
Dictionary<string, SubToolset> subToolsetsAsDictionary = subToolsets as Dictionary<string, SubToolset>;
_subToolsets = subToolsetsAsDictionary ?? new Dictionary<string, SubToolset>(subToolsets);
}
if (subToolsetsAsDictionary != null)
{
_subToolsets = subToolsetsAsDictionary;
}
else
{
_subToolsets = new Dictionary<string, SubToolset>(subToolsets);
}
if (importSearchPathsTable != null)
{
_propertySearchPathsTable = importSearchPathsTable;
}
}
@ -350,29 +348,36 @@ namespace Microsoft.Build.Evaluation
}
/// <summary>
/// Returns a copy of the list of search paths for a MSBuildExtensionsPath* property kind.
/// Returns a ProjectImportPathMatch struct for the first property found in the expression for which
/// project import search paths is enabled.
/// <param name="expression">Expression to search for properties in (first level only, not recursive)</param>
/// <returns>List of search paths or ProjectImportPathMatch.None if empty</returns>
/// </summary>
internal IList<string> GetMSBuildExtensionsPathSearchPathsFor(MSBuildExtensionsPathReferenceKind refKind)
internal ProjectImportPathMatch GetProjectImportSearchPaths(string expression)
{
IList<string> paths;
if (MSBuildExtensionsPathSearchPathsTable != null && MSBuildExtensionsPathSearchPathsTable.TryGetValue(refKind, out paths))
if (string.IsNullOrEmpty(expression) || ImportPropertySearchPathsTable == null)
{
return new List<string>(paths);
return ProjectImportPathMatch.None;
}
return new List<string>();
foreach (var searchPath in _propertySearchPathsTable)
{
if (expression.IndexOf($"$({searchPath.Key})", StringComparison.OrdinalIgnoreCase) >= 0)
{
return new ProjectImportPathMatch(searchPath.Key, searchPath.Value);
}
}
return ProjectImportPathMatch.None;
}
/// <summary>
/// Name of this toolset
/// </summary>
public string ToolsVersion
{
get { return _toolsVersion; }
}
public string ToolsVersion => _toolsVersion;
/// <summary>
/// Path to this toolset's tasks and targets. Corresponds to $(MSBuildToolsPath) in a project or targets file.
/// Path to this toolset's tasks and targets. Corresponds to $(MSBuildToolsPath) in a project or targets file.
/// </summary>
public string ToolsPath
{
@ -567,18 +572,17 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Path to look for msbuild override task files.
/// </summary>
internal string OverrideTasksPath
{
get { return _overrideTasksPath; }
}
internal string OverrideTasksPath => _overrideTasksPath;
/// <summary>
/// ToolsVersion to use as the default ToolsVersion for this version of MSBuild
/// </summary>
internal string DefaultOverrideToolsVersion
{
get { return _defaultOverrideToolsVersion; }
}
internal string DefaultOverrideToolsVersion => _defaultOverrideToolsVersion;
/// <summary>
/// Map of properties to their list of fall-back search paths
/// </summary>
internal Dictionary<string, List<string>> ImportPropertySearchPathsTable => _propertySearchPathsTable;
/// <summary>
/// Map of MSBuildExtensionsPath properties to their list of fallback search paths
@ -601,6 +605,7 @@ namespace Microsoft.Build.Evaluation
translator.TranslateDictionary(ref _subToolsets, StringComparer.OrdinalIgnoreCase, SubToolset.FactoryForDeserialization);
translator.Translate(ref _overrideTasksPath);
translator.Translate(ref _defaultOverrideToolsVersion);
translator.TranslateDictionaryList(ref _propertySearchPathsTable, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
@ -654,18 +659,13 @@ namespace Microsoft.Build.Evaluation
property = subToolset.Properties[propertyName];
}
if (property == null)
{
property = Properties[propertyName];
}
return property;
return property ?? (Properties[propertyName]);
}
/// <summary>
/// Factory for deserialization.
/// </summary>
static internal Toolset FactoryForDeserialization(INodePacketTranslator translator)
internal static Toolset FactoryForDeserialization(INodePacketTranslator translator)
{
Toolset toolset = new Toolset(translator);
return toolset;
@ -812,12 +812,7 @@ namespace Microsoft.Build.Evaluation
// Solution version also didn't work out, so fall back to default.
// If subToolsetVersion is null, there simply wasn't a matching solution version.
if (subToolsetVersion == null)
{
subToolsetVersion = DefaultSubToolsetVersion;
}
return subToolsetVersion;
return subToolsetVersion ?? (DefaultSubToolsetVersion);
}
/// <summary>

Просмотреть файл

@ -8,7 +8,9 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using Microsoft.Build.Construction;
using Microsoft.Build.Collections;
using Microsoft.Build.Construction;
using Microsoft.Build.Execution;
@ -19,11 +21,6 @@ using InvalidToolsetDefinitionException = Microsoft.Build.Exceptions.InvalidTool
namespace Microsoft.Build.Evaluation
{
/// <summary>
/// Delegate for unit test purposes only
/// </summary>
internal delegate Configuration ReadApplicationConfiguration();
/// <summary>
/// Class used to read toolset configurations.
/// </summary>
@ -37,7 +34,7 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Delegate used to read application configurations
/// </summary>
private ReadApplicationConfiguration _readApplicationConfiguration = null;
private readonly Func<Configuration> _readApplicationConfiguration;
/// <summary>
/// Flag indicating that an attempt has been made to read the configuration
@ -51,27 +48,27 @@ namespace Microsoft.Build.Evaluation
private char _separatorForExtensionsPathSearchPaths = ';';
/// <summary>
/// map of MSBuildExtensionsPath property kind to list of fallback search paths, per toolsVersion
/// Cached values of tools version -> project import search paths table
/// </summary>
private Dictionary<string, Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>>> _kindToPathsCachePerToolsVersion;
private readonly Dictionary<string, Dictionary<string, List<string>>> _projectImportSearchPathsCache;
/// <summary>
/// Default constructor
/// </summary>
internal ToolsetConfigurationReader(PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties)
: this(environmentProperties, globalProperties, new ReadApplicationConfiguration(ToolsetConfigurationReader.ReadApplicationConfiguration))
: this(environmentProperties, globalProperties, ReadApplicationConfiguration)
{
}
/// <summary>
/// Constructor taking a delegate for unit test purposes only
/// </summary>
internal ToolsetConfigurationReader(PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, ReadApplicationConfiguration readApplicationConfiguration)
internal ToolsetConfigurationReader(PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, Func<Configuration> readApplicationConfiguration)
: base(environmentProperties, globalProperties)
{
ErrorUtilities.VerifyThrowArgumentNull(readApplicationConfiguration, "readApplicationConfiguration");
_readApplicationConfiguration = readApplicationConfiguration;
_kindToPathsCachePerToolsVersion = new Dictionary<string, Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>>>(StringComparer.OrdinalIgnoreCase);
_projectImportSearchPathsCache = new Dictionary<string, Dictionary<string, List<string>>>(StringComparer.OrdinalIgnoreCase);
}
/// <summary>
@ -100,46 +97,24 @@ namespace Microsoft.Build.Evaluation
yield return new ToolsetPropertyDefinition(toolset.toolsVersion, string.Empty, location);
}
}
else
{
yield break;
}
}
}
/// <summary>
/// Returns the default tools version, or null if none was specified
/// </summary>
protected override string DefaultToolsVersion
{
get
{
return (ConfigurationSection == null ? null : ConfigurationSection.Default);
}
}
protected override string DefaultToolsVersion => ConfigurationSection?.Default;
/// <summary>
/// Returns the path to find overridetasks, or null if none was specified
/// Returns the path to find override tasks, or null if none was specified
/// </summary>
protected override string MSBuildOverrideTasksPath
{
get
{
return (ConfigurationSection == null ? null : ConfigurationSection.MSBuildOverrideTasksPath);
}
}
protected override string MSBuildOverrideTasksPath => ConfigurationSection?.MSBuildOverrideTasksPath;
/// <summary>
/// DefaultOverrideToolsVersion attribute on msbuildToolsets element, specifying the toolsversion that should be used by
/// DefaultOverrideToolsVersion attribute on msbuildToolsets element, specifying the tools version that should be used by
/// default to build projects with this version of MSBuild.
/// </summary>
protected override string DefaultOverrideToolsVersion
{
get
{
return (ConfigurationSection == null ? null : ConfigurationSection.DefaultOverrideToolsVersion);
}
}
protected override string DefaultOverrideToolsVersion => ConfigurationSection?.DefaultOverrideToolsVersion;
/// <summary>
/// Lazy getter for the ToolsetConfigurationSection
@ -200,11 +175,11 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Provides an enumerator over the set of sub-toolset names available to a particular
/// toolsversion. MSBuild config files do not currently support sub-toolsets, so
/// tools version. MSBuild config files do not currently support sub-toolsets, so
/// we return nothing.
/// </summary>
/// <param name="toolsVersion">The tools version.</param>
/// <returns>An enumeration of the sub-toolsets that belong to that toolsversion.</returns>
/// <returns>An enumeration of the sub-toolsets that belong to that tools version.</returns>
protected override IEnumerable<string> GetSubToolsetVersions(string toolsVersion)
{
yield break;
@ -224,68 +199,56 @@ namespace Microsoft.Build.Evaluation
}
/// <summary>
/// Returns a map of MSBuildExtensionsPath* property names/kind to list of search paths
/// Returns a map of project property names / list of search paths for the specified toolsVersion and os
/// </summary>
protected override Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> GetMSBuildExtensionPathsSearchPathsTable(string toolsVersion, string os)
protected override Dictionary<string, List<string>> GetProjectImportSearchPathsTable(string toolsVersion, string os)
{
Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> kindToPathsCache;
Dictionary<string, List<string>> kindToPathsCache;
var key = toolsVersion + ":" + os;
if (_kindToPathsCachePerToolsVersion.TryGetValue(key, out kindToPathsCache))
if (_projectImportSearchPathsCache.TryGetValue(key, out kindToPathsCache))
{
return kindToPathsCache;
}
// Read and populate the map
kindToPathsCache = new Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>>();
_kindToPathsCachePerToolsVersion[key] = kindToPathsCache;
kindToPathsCache = new Dictionary<string, List<string>>();
_projectImportSearchPathsCache[key] = kindToPathsCache;
ToolsetElement toolsetElement = ConfigurationSection.Toolsets.GetElement(toolsVersion);
var propertyCollection = toolsetElement?.AllMSBuildExtensionPathsSearchPaths?.GetElement(os)?.PropertyElements;
var propertyCollection = toolsetElement?.AllProjectImportSearchPaths?.GetElement(os)?.PropertyElements;
if (propertyCollection == null || propertyCollection.Count == 0)
{
return kindToPathsCache;
}
var allPaths = new MSBuildExtensionsPathReferenceKind[] {
MSBuildExtensionsPathReferenceKind.Default,
MSBuildExtensionsPathReferenceKind.Path32,
MSBuildExtensionsPathReferenceKind.Path64,
MSBuildExtensionsPathReferenceKind.None
};
foreach (MSBuildExtensionsPathReferenceKind kind in allPaths)
{
kindToPathsCache[kind] = ComputeDistinctListOfFallbackPathsFor(kind, propertyCollection);
}
kindToPathsCache = ComputeDistinctListOfSearchPaths(propertyCollection);
return kindToPathsCache;
}
/// <summary>
/// Returns a list of the search paths for a given MSBuildExtensionsPathReferenceKind
/// Returns a list of the search paths for a given search path property collection
/// </summary>
private List<string> ComputeDistinctListOfFallbackPathsFor(MSBuildExtensionsPathReferenceKind refKind, ToolsetElement.PropertyElementCollection propertyCollection)
private Dictionary<string, List<string>> ComputeDistinctListOfSearchPaths(ToolsetElement.PropertyElementCollection propertyCollection)
{
var extnPaths = new List<string>();
var pathsFromConfig = propertyCollection.GetElement(refKind.StringRepresentation)?.Value;
var pathsTable = new Dictionary<string, List<string>>();
//FIXME: handle ; in path on Unix
if (String.IsNullOrEmpty(pathsFromConfig))
foreach (ToolsetElement.PropertyElement property in propertyCollection)
{
return extnPaths;
}
var pathsTable = new HashSet<string>();
foreach (var extnPath in pathsFromConfig.Split(new char[]{_separatorForExtensionsPathSearchPaths}, StringSplitOptions.RemoveEmptyEntries))
{
if (!pathsTable.Contains(extnPath))
if (string.IsNullOrEmpty(property.Value) || string.IsNullOrEmpty(property.Name))
{
pathsTable.Add(extnPath);
extnPaths.Add(extnPath);
continue;
}
//FIXME: handle ; in path on Unix
var paths =
property.Value.Split(new[] {_separatorForExtensionsPathSearchPaths},
StringSplitOptions.RemoveEmptyEntries).Distinct();
pathsTable.Add(property.Name, paths.ToList());
}
return extnPaths;
return pathsTable;
}
/// <summary>
@ -295,14 +258,17 @@ namespace Microsoft.Build.Evaluation
/// </summary>
private static Configuration ReadApplicationConfiguration()
{
if (FileUtilities.RunningTests)
var msbuildExeConfig = FileUtilities.CurrentExecutableConfigurationFilePath;
// When running from the command-line or from VS, use the msbuild.exe.config file
if (!FileUtilities.RunningTests && File.Exists(msbuildExeConfig))
{
return ConfigurationManager.OpenExeConfiguration(FileUtilities.CurrentExecutablePath);
}
else
{
return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var configFile = new ExeConfigurationFileMap { ExeConfigFilename = msbuildExeConfig };
return ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
}
// When running tests or the expected config file doesn't exist, fall-back to default
return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
}
}
}

Просмотреть файл

@ -64,14 +64,14 @@ namespace Microsoft.Build.Evaluation
return Enumerable.Empty<ToolsetPropertyDefinition>();
}
protected override Dictionary<string, List<string>> GetProjectImportSearchPathsTable(string toolsVersion, string os)
{
return new Dictionary<string, List<string>>();
}
protected override IEnumerable<string> GetSubToolsetVersions(string toolsVersion)
{
return Enumerable.Empty<string>();
}
protected override Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> GetMSBuildExtensionPathsSearchPathsTable(string toolsVersion, string os)
{
return new Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>>();
}
}
}

Просмотреть файл

@ -6,16 +6,15 @@
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Build.Shared;
using Microsoft.Build.Collections;
using Microsoft.Build.Execution;
using Microsoft.Build.Internal;
using Microsoft.Build.Shared;
using error = Microsoft.Build.Shared.ErrorUtilities;
using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
using InvalidToolsetDefinitionException = Microsoft.Build.Exceptions.InvalidToolsetDefinitionException;
@ -130,8 +129,7 @@ namespace Microsoft.Build.Evaluation
string defaultOverrideToolsVersionFromConfiguration = null;
#if FEATURE_SYSTEM_CONFIGURATION
if ((locations & ToolsetDefinitionLocations.ConfigurationFile)
== ToolsetDefinitionLocations.ConfigurationFile)
if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
{
if (configurationReader == null && ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets())
{
@ -144,12 +142,8 @@ namespace Microsoft.Build.Evaluation
if (configurationReader != null)
{
// Accumulation of properties is okay in the config file because it's deterministically ordered
defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(
toolsets,
globalProperties,
initialProperties,
true /* accumulate properties */,
out overrideTasksPathFromConfiguration,
defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
out defaultOverrideToolsVersionFromConfiguration);
}
}
@ -163,21 +157,16 @@ namespace Microsoft.Build.Evaluation
{
#if FEATURE_WIN32_REGISTRY
if (NativeMethodsShared.IsWindows || registryReader != null)
{
var registryReaderToUse = registryReader
?? new ToolsetRegistryReader(environmentProperties, globalProperties);
// If we haven't been provided a registry reader (i.e. unit tests), create one
registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties);
// We do not accumulate properties when reading them from the registry, because the order
// in which values are returned to us is essentially random: so we disallow one property
// in the registry to refer to another also in the registry
defaultToolsVersionFromRegistry = registryReaderToUse.ReadToolsets(
toolsets,
globalProperties,
initialProperties,
false /* do not accumulate properties */,
out overrideTasksPathFromRegistry,
out defaultOverrideToolsVersionFromRegistry);
}
// We do not accumulate properties when reading them from the registry, because the order
// in which values are returned to us is essentially random: so we disallow one property
// in the registry to refer to another also in the registry
defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties,
initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry,
out defaultOverrideToolsVersionFromRegistry);
}
else
#endif
{
@ -411,7 +400,7 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Returns a map of MSBuildExtensionsPath* property names/kind to list of search paths
/// </summary>
protected abstract Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> GetMSBuildExtensionPathsSearchPathsTable(string toolsVersion, string os);
protected abstract Dictionary<string, List<string>> GetProjectImportSearchPathsTable(string toolsVersion, string os);
/// <summary>
/// Reads all the toolsets and populates the given ToolsetCollection with them
@ -515,8 +504,8 @@ namespace Microsoft.Build.Evaluation
try
{
toolset = new Toolset(toolsVersion.Name, toolsPath == null ? binPath : toolsPath, properties, _environmentProperties, globalProperties, subToolsets, MSBuildOverrideTasksPath, DefaultOverrideToolsVersion);
toolset.MSBuildExtensionsPathSearchPathsTable = GetMSBuildExtensionPathsSearchPathsTable(toolsVersion.Name, NativeMethodsShared.GetOSNameForExtensionsPath());
var importSearchPathsTable = GetProjectImportSearchPathsTable(toolsVersion.Name, NativeMethodsShared.GetOSNameForExtensionsPath());
toolset = new Toolset(toolsVersion.Name, toolsPath == null ? binPath : toolsPath, properties, _environmentProperties, globalProperties, subToolsets, MSBuildOverrideTasksPath, DefaultOverrideToolsVersion, importSearchPathsTable);
}
catch (ArgumentException e)
{
@ -540,7 +529,6 @@ namespace Microsoft.Build.Evaluation
{
return null;
}
PropertyDictionary<ProjectPropertyInstance> buildProperties =
new PropertyDictionary<ProjectPropertyInstance>();
AppendStandardProperties(buildProperties, globalProperties, version, root, toolsPath);

Просмотреть файл

@ -292,9 +292,9 @@ namespace Microsoft.Build.Evaluation
/// <summary>
/// Returns a map of MSBuildExtensionsPath* property names/kind to list of search paths
/// </summary>
protected override Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> GetMSBuildExtensionPathsSearchPathsTable(string toolsVersion, string os)
protected override Dictionary<string, List<string>> GetProjectImportSearchPathsTable(string toolsVersion, string os)
{
return new Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>>();
return new Dictionary<string, List<string>>();
}
/// <summary>

Просмотреть файл

@ -457,15 +457,24 @@ namespace Microsoft.Build.Evaluation
// Maybe we need to generate an error for invalid characters in itemgroup name?
// For now, just let item evaluation handle the error.
bool fInReplacement = false;
int parenToClose = 0;
while (_parsePoint < _expression.Length)
{
if (_expression[_parsePoint] == '\'')
{
fInReplacement = !fInReplacement;
}
else if (_expression[_parsePoint] == '(' && !fInReplacement)
{
parenToClose++;
}
else if (_expression[_parsePoint] == ')' && !fInReplacement)
{
break;
if (parenToClose == 0)
{
break;
}
else { parenToClose--; }
}
_parsePoint++;
}

Просмотреть файл

@ -2023,36 +2023,31 @@ namespace Microsoft.Build.Evaluation
}
/// <summary>
/// If the project import references a $(MSBuildExtensionsPath*)
/// then this tries to find project files corresponding to that, using various search
/// paths. It relies on the ExpandAndLoadImportsFromUnescapedImportExpressionConditioned
/// to do the actual loading and parsing.
/// This is explained in detail in a comment with the method code.
///
/// If the project import does not reference the $(MSBuildExtensionsPath*) property, then
/// it falls back to the default behavior.
///
/// Caches the parsed import into the provided collection, so future
/// requests can be satisfied without re-parsing it.
/// Expands and loads project imports.
/// <remarks>
/// Imports may contain references to "projectImportSearchPaths" defined in the app.config
/// toolset section. If this is the case, this method will search for the imported project
/// in those additional paths if the default fails.
/// </remarks>
/// </summary>
private List<ProjectRootElement> ExpandAndLoadImports(string directoryOfImportingFile, ProjectImportElement importElement)
{
var refKindInProject = MSBuildExtensionsPathReferenceKind.FindIn(importElement.Project);
var fallbackExtensionPaths = _data.Toolset.GetMSBuildExtensionsPathSearchPathsFor(refKindInProject);
var fallbackSearchPathMatch = _data.Toolset.GetProjectImportSearchPaths(importElement.Project);
// no reference or we need to lookup only the default path,
// so, use the Import path
if (fallbackExtensionPaths.Count == 0)
if (fallbackSearchPathMatch.Equals(ProjectImportPathMatch.None))
{
List<ProjectRootElement> projects;
var result = ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(directoryOfImportingFile, importElement, importElement.Project, out projects);
ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(directoryOfImportingFile, importElement, importElement.Project, out projects);
return projects;
}
// $(MSBuildExtensionsPath*) usually resolves to a single value, single default path. This can be overridden
// by the usual property overriding techniques.
// Note: Any property defined in the <projectImportSearchPaths> section can be replaced, MSBuildExtensionsPath
// is used here as an example of behavior.
// $(MSBuildExtensionsPath*) usually resolves to a single value, single default path
//
// Eg. <Import Project='$(MSBuildExtensionsPath)\foo\extn.proj' />
// Eg. <Import Project='$(MSBuildExtensionsPath)\foo\extn.proj' />
//
// But this feature allows that when it is used in an Import element, it will behave as a "search path", meaning
// that the relative project path "foo\extn.proj" will be searched for, in more than one location.
@ -2063,17 +2058,17 @@ namespace Microsoft.Build.Evaluation
//
// 1. The value of the MSBuildExtensionsPath* property
//
// 2. Search paths available in the current toolset (via toolset.MSBuildExtensionsPathSearchPathsTable).
// 2. Search paths available in the current toolset (via toolset.ImportPropertySearchPathsTable).
// That may be loaded from app.config with a definition like:
//
// <toolset .. >
// <msbuildExtensionsPathSearchPaths>
// <projectImportSearchPaths>
// <searchPaths os="osx">
// <property name="MSBuildExtensionsPath" value="/Library/Frameworks/Mono.framework/External/xbuild/;/tmp/foo"/>
// <property name="MSBuildExtensionsPath32" value="/Library/Frameworks/Mono.framework/External/xbuild/"/>
// <property name="MSBuildExtensionsPath64" value="/Library/Frameworks/Mono.framework/External/xbuild/"/>
// </searchPaths>
// </msbuildExtensionsPathSearchPaths>
// </projectImportSearchPaths>
// </toolset>
//
// This is available only when used in an Import element and it's Condition. So, the following common pattern
@ -2082,7 +2077,7 @@ namespace Microsoft.Build.Evaluation
// <Import Project="$(MSBuildExtensionsPath)\foo\extn.proj" Condition="'Exists('$(MSBuildExtensionsPath)\foo\extn.proj')'" />
//
// The value of the MSBuildExtensionsPath* property, will always be "visible" with it's default value, example, when read or
// referenced anywhere else. This is a very limited support, so, it doesn't come in to effect if the explcit reference to
// referenced anywhere else. This is a very limited support, so, it doesn't come in to effect if the explicit reference to
// the $(MSBuildExtensionsPath) property is not present in the Project attribute of the Import element. So, the following is
// not supported:
//
@ -2091,27 +2086,35 @@ namespace Microsoft.Build.Evaluation
//
// Adding the value of $(MSBuildExtensionsPath*) property to the list of search paths
fallbackExtensionPaths.Insert(0, _data.GetProperty(refKindInProject.StringRepresentation).EvaluatedValue);
var prop = _data.GetProperty(fallbackSearchPathMatch.PropertyName);
string extensionPropertyRefAsString = refKindInProject.MSBuildPropertyName;
var pathsToSearch =
// The actual value of the property, with no fallbacks
new[] {prop.EvaluatedValue}
// The list of fallbacks, in order
.Concat(fallbackSearchPathMatch.SearchPaths).ToList();
string extensionPropertyRefAsString = fallbackSearchPathMatch.MsBuildPropertyFormat;
_loggingService.LogComment(_buildEventContext, MessageImportance.Low, "SearchPathsForMSBuildExtensionsPath",
extensionPropertyRefAsString,
String.Join(Path.PathSeparator.ToString(), fallbackExtensionPaths));
String.Join(Path.PathSeparator.ToString(), pathsToSearch));
bool atleastOneExactFilePathWasLookedAtAndNotFound = false;
// Try every extension search path, till we get a Hit:
// 1. 1 or more project files loaded
// 2. 1 or more project files *found* but ignored (like circular, self imports)
foreach (var extensionPath in fallbackExtensionPaths)
foreach (var extensionPath in pathsToSearch)
{
if (!Directory.Exists(extensionPath))
string extensionPathExpanded = _data.ExpandString(extensionPath);
if (!Directory.Exists(extensionPathExpanded))
{
continue;
}
var newExpandedCondition = importElement.Condition.Replace(extensionPropertyRefAsString, extensionPath);
var newExpandedCondition = importElement.Condition.Replace(extensionPropertyRefAsString, extensionPathExpanded);
if (!EvaluateConditionCollectingConditionedProperties(importElement, newExpandedCondition, ExpanderOptions.ExpandProperties, ParserOptions.AllowProperties,
_projectRootElementCache))
{
@ -2119,9 +2122,9 @@ namespace Microsoft.Build.Evaluation
}
var newExpandedImportPath = importElement.Project;
newExpandedImportPath = newExpandedImportPath.Replace(extensionPropertyRefAsString, extensionPath);
newExpandedImportPath = newExpandedImportPath.Replace(extensionPropertyRefAsString, extensionPathExpanded);
_loggingService.LogComment(_buildEventContext, MessageImportance.Low, "TryingExtensionsPath", newExpandedImportPath, extensionPath);
_loggingService.LogComment(_buildEventContext, MessageImportance.Low, "TryingExtensionsPath", newExpandedImportPath, extensionPathExpanded);
List<ProjectRootElement> projects;
var result = ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, newExpandedImportPath,
@ -2152,7 +2155,7 @@ namespace Microsoft.Build.Evaluation
// was a wildcard and it resolved to zero files!
if (atleastOneExactFilePathWasLookedAtAndNotFound && (_loadSettings & ProjectLoadSettings.IgnoreMissingImports) == 0)
{
ThrowForImportedProjectFromExtensionsPathNotFound(refKindInProject, importElement);
ThrowForImportedProjectWithSearchPathsNotFound(fallbackSearchPathMatch, importElement);
}
return new List<ProjectRootElement>();
@ -2516,37 +2519,39 @@ namespace Microsoft.Build.Evaluation
}
/// <summary>
/// Throws InvalidProjectException because we failed to import a project from $(MSBuildExtensionsPath*)
/// <param name="refKindInProject">MSBuildExtensionsPath reference kind found in the Project attribute of the Import element</param>
/// Throws InvalidProjectException because we failed to import a project which contained a ProjectImportSearchPath fall-back.
/// <param name="searchPathMatch">MSBuildExtensionsPath reference kind found in the Project attribute of the Import element</param>
/// <param name="importElement">The importing element for this import</param>
/// </summary>
private void ThrowForImportedProjectFromExtensionsPathNotFound(MSBuildExtensionsPathReferenceKind refKindInProject, ProjectImportElement importElement)
private void ThrowForImportedProjectWithSearchPathsNotFound(ProjectImportPathMatch searchPathMatch, ProjectImportElement importElement)
{
string extensionsPathPropValue = _data.GetProperty(refKindInProject.StringRepresentation).EvaluatedValue;
string extensionsPathPropValue = _data.GetProperty(searchPathMatch.PropertyName).EvaluatedValue;
string importExpandedWithDefaultPath = _expander.ExpandIntoStringLeaveEscaped(
importElement.Project.Replace(refKindInProject.MSBuildPropertyName, extensionsPathPropValue),
importElement.Project.Replace(searchPathMatch.MsBuildPropertyFormat, extensionsPathPropValue),
ExpanderOptions.ExpandProperties, importElement.ProjectLocation);
string relativeProjectPath = FileUtilities.MakeRelative(extensionsPathPropValue, importExpandedWithDefaultPath);
var onlyFallbackSearchPaths = _data.Toolset.GetMSBuildExtensionsPathSearchPathsFor(refKindInProject);
var onlyFallbackSearchPaths = searchPathMatch.SearchPaths.Select(s => _data.ExpandString(s)).ToList();
string stringifiedListOfSearchPaths = StringifyList(onlyFallbackSearchPaths);
#if FEATURE_SYSTEM_CONFIGURATION
string configLocation = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
ProjectErrorUtilities.ThrowInvalidProject(importElement.ProjectLocation, "ImportedProjectFromExtensionsPathNotFoundFromAppConfig",
importExpandedWithDefaultPath,
relativeProjectPath,
refKindInProject.MSBuildPropertyName,
stringifiedListOfSearchPaths,
configLocation);
ProjectErrorUtilities.ThrowInvalidProject(importElement.ProjectLocation,
"ImportedProjectFromExtensionsPathNotFoundFromAppConfig",
importExpandedWithDefaultPath,
relativeProjectPath,
searchPathMatch.MsBuildPropertyFormat,
stringifiedListOfSearchPaths,
configLocation);
#else
ProjectErrorUtilities.ThrowInvalidProject(importElement.ProjectLocation, "ImportedProjectFromExtensionsPathNotFound",
importExpandedWithDefaultPath,
relativeProjectPath,
refKindInProject.MSBuildPropertyName,
searchPathMatch.MsBuildPropertyFormat,
stringifiedListOfSearchPaths);
#endif
}
@ -2565,7 +2570,7 @@ namespace Microsoft.Build.Evaluation
if (i > 0)
{
sb.Append(", ");
}
}
sb.Append($"\"{strings[i]}\"");
}

Просмотреть файл

@ -184,7 +184,7 @@ namespace Microsoft.Build.Evaluation
XmlDocument innerDocument = resolved.XmlDocument;
string importTag = " <Import Project=\"" + importProject + "\"" + ((importCondition.Length > 0) ? " Condition=\"" + importCondition + "\"" : String.Empty) + ">";
destination.AppendChild(destination.OwnerDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n" + importTag + "\r\n\r\n" + resolved.FullPath.Replace("--", "__") + "\r\n" + new String('=', 140) + "\r\n"));
destination.AppendChild(destinationDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n" + importTag + "\r\n\r\n" + resolved.FullPath.Replace("--", "__") + "\r\n" + new String('=', 140) + "\r\n"));
_filePaths.Push(resolved.FullPath);
CloneChildrenResolvingImports(innerDocument, destination);
@ -192,11 +192,11 @@ namespace Microsoft.Build.Evaluation
if (i < resolvedList.Count - 1)
{
destination.AppendChild(destination.OwnerDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n </Import>\r\n" + new String('=', 140) + "\r\n"));
destination.AppendChild(destinationDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n </Import>\r\n" + new String('=', 140) + "\r\n"));
}
else
{
destination.AppendChild(destination.OwnerDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n </Import>\r\n\r\n" + _filePaths.Peek()?.Replace("--", "__") + "\r\n" + new String('=', 140) + "\r\n"));
destination.AppendChild(destinationDocument.CreateComment("\r\n" + new String('=', 140) + "\r\n </Import>\r\n\r\n" + _filePaths.Peek()?.Replace("--", "__") + "\r\n" + new String('=', 140) + "\r\n"));
}
}
@ -227,4 +227,4 @@ namespace Microsoft.Build.Evaluation
}
}
}
}
}

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.Build.Construction
/// <summary>
/// This class will cache string values for loaded Xml files.
/// </summary>
[DebuggerDisplay("#Strings={Count} #Documents={documents.Count}")]
[DebuggerDisplay("#Strings={Count} #Documents={_documents.Count}")]
internal class ProjectStringCache
{
/// <summary>
@ -228,7 +228,7 @@ namespace Microsoft.Build.Construction
/// Represents an entry in the ProjectStringCache.
/// Can't be a struct because the copy-by-value and the ref counting don't go well together.
/// </summary>
[DebuggerDisplay("Count={refCount} String={cachedString}")]
[DebuggerDisplay("Count={_refCount} String={_cachedString}")]
private class StringCacheEntry : IKeyed
{
/// <summary>

Просмотреть файл

@ -42,7 +42,7 @@ namespace Microsoft.Build.Execution
/// Implementation of HostServices that
/// mediates access from the build to the host.
/// </summary>
[DebuggerDisplay("#Entries={hostObjectMap.Count}")]
[DebuggerDisplay("#Entries={_hostObjectMap.Count}")]
public class HostServices
{
/// <summary>
@ -232,7 +232,7 @@ namespace Microsoft.Build.Execution
/// <summary>
/// Bag holding host object information for a single project file.
/// </summary>
[DebuggerDisplay("#HostObjects={hostObjects.Count}")]
[DebuggerDisplay("#HostObjects={_hostObjects.Count}")]
private class HostObjects
{
/// <summary>

Просмотреть файл

@ -1818,6 +1818,11 @@ namespace Microsoft.Build.Execution
if (loggers != null)
{
parameters.Loggers = (loggers is ICollection<ILogger>) ? ((ICollection<ILogger>)loggers) : new List<ILogger>(loggers);
// Enables task parameter logging based on whether any of the loggers attached
// to the Project have their verbosity set to Diagnostic. If no logger has
// been set to log diagnostic then the existing/default value will be persisted.
parameters.LogTaskInputs = parameters.LogTaskInputs || loggers.Any(logger => logger.Verbosity == LoggerVerbosity.Diagnostic);
}
if (remoteLoggers != null)

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Build.Execution
/// An evaluated item definition for a particular item-type, divested of all references to XML.
/// Immutable.
/// </summary>
[DebuggerDisplay("{itemType} #Metadata={MetadataCount}")]
[DebuggerDisplay("{_itemType} #Metadata={MetadataCount}")]
public class ProjectItemDefinitionInstance : IKeyed, IMetadataTable, IItemDefinition<ProjectMetadataInstance>
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// Wraps an unevaluated itemgroup under a target.
/// Immutable.
/// </summary>
[DebuggerDisplay("Condition={condition}")]
[DebuggerDisplay("Condition={_condition}")]
public class ProjectItemGroupTaskInstance : ProjectTargetInstanceChild
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// Wraps an unevaluated item under an itemgroup in a target.
/// Immutable.
/// </summary>
[DebuggerDisplay("{itemType} Include={include} Exclude={exclude} Remove={remove} Condition={condition}")]
[DebuggerDisplay("{_itemType} Include={_include} Exclude={_exclude} Remove={_remove} Condition={_condition}")]
public class ProjectItemGroupTaskItemInstance
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// Wraps an unevaluated metadatum under an item in an itemgroup in a target
/// Immutable.
/// </summary>
[DebuggerDisplay("{name} Value={value} Condition={condition}")]
[DebuggerDisplay("{_name} Value={_value} Condition={_condition}")]
public class ProjectItemGroupTaskMetadataInstance
{
/// <summary>

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Build.Execution
/// Added and removed via methods on the ProjectItemInstance object.
/// IMMUTABLE OBJECT.
/// </summary>
[DebuggerDisplay("{name}={EvaluatedValue}")]
[DebuggerDisplay("{_name}={EvaluatedValue}")]
public class ProjectMetadataInstance : IKeyed, IValued, IEquatable<ProjectMetadataInstance>, INodePacketTranslatable, IMetadatum, IDeepCloneable<ProjectMetadataInstance>, IImmutable
{
/// <summary>

Просмотреть файл

@ -18,7 +18,7 @@ namespace Microsoft.Build.Execution
/// <remarks>
/// This is an immutable class
/// </remarks>
[DebuggerDisplay("ExecuteTargets={executeTargets} Condition={condition}")]
[DebuggerDisplay("ExecuteTargets={_executeTargets} Condition={_condition}")]
public sealed class ProjectOnErrorInstance : ProjectTargetInstanceChild
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// Wraps an unevaluated propertygroup under a target.
/// Immutable.
/// </summary>
[DebuggerDisplay("Condition={condition}")]
[DebuggerDisplay("Condition={_condition}")]
public class ProjectPropertyGroupTaskInstance : ProjectTargetInstanceChild
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// Wraps an unevaluated property under an propertygroup in a target.
/// Immutable.
/// </summary>
[DebuggerDisplay("{name}={Value} Condition={condition}")]
[DebuggerDisplay("{_name}={Value} Condition={_condition}")]
public class ProjectPropertyGroupTaskPropertyInstance
{
/// <summary>

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.Build.Execution
/// Wraps an evaluated property for build purposes.
/// Added and removed via methods on the ProjectInstance object.
/// </summary>
[DebuggerDisplay("{name}={escapedValue}")]
[DebuggerDisplay("{_name}={_escapedValue}")]
public class ProjectPropertyInstance : IKeyed, IValued, IProperty, IEquatable<ProjectPropertyInstance>, INodePacketTranslatable, IDeepCloneable<ProjectPropertyInstance>
{
/// <summary>

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Build.Execution
/// <remarks>
/// This is an immutable class.
/// </remarks>
[DebuggerDisplay("Name={name} Count={children.Count} Condition={condition} Inputs={inputs} Outputs={outputs} DependsOnTargets={dependsOnTargets}")]
[DebuggerDisplay("Name={_name} Count={_children.Count} Condition={_condition} Inputs={_inputs} Outputs={_outputs} DependsOnTargets={_dependsOnTargets}")]
public sealed class ProjectTargetInstance : IImmutable, IKeyed
{
/// <summary>

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution
/// <remarks>
/// This is an immutable class
/// </remarks>
[DebuggerDisplay("Name={name} Condition={condition} ContinueOnError={continueOnError} MSBuildRuntime={MSBuildRuntime} MSBuildArchitecture={MSBuildArchitecture} #Parameters={parameters.Count} #Outputs={outputs.Count}")]
[DebuggerDisplay("Name={_name} Condition={_condition} ContinueOnError={_continueOnError} MSBuildRuntime={MSBuildRuntime} MSBuildArchitecture={MSBuildArchitecture} #Parameters={_parameters.Count} #Outputs={_outputs.Count}")]
public sealed class ProjectTaskInstance : ProjectTargetInstanceChild
{
/// <summary>

Просмотреть файл

@ -430,6 +430,48 @@ namespace Microsoft.Build.BackEnd.Logging
}
}
/// <summary>
/// Sets foreground color to color specified using ANSI escape codes
/// </summary>
/// <param name="c">foreground color</param>
internal static void SetColorANSI(ConsoleColor c)
{
string colorString = "\x1b[";
switch (c)
{
case ConsoleColor.Black: colorString += "30"; break;
case ConsoleColor.DarkBlue: colorString += "34"; break;
case ConsoleColor.DarkGreen: colorString += "32"; break;
case ConsoleColor.DarkCyan: colorString += "36"; break;
case ConsoleColor.DarkRed: colorString += "31"; break;
case ConsoleColor.DarkMagenta: colorString += "35"; break;
case ConsoleColor.DarkYellow: colorString += "33"; break;
case ConsoleColor.Gray: colorString += "37"; break;
case ConsoleColor.DarkGray: colorString += "30;1"; break;
case ConsoleColor.Blue: colorString += "34;1"; break;
case ConsoleColor.Green: colorString += "32;1"; break;
case ConsoleColor.Cyan: colorString += "36;1"; break;
case ConsoleColor.Red: colorString += "31;1"; break;
case ConsoleColor.Magenta: colorString += "35;1"; break;
case ConsoleColor.Yellow: colorString += "33;1"; break;
case ConsoleColor.White: colorString += "37;1"; break;
default: colorString = ""; break;
}
if ("" != colorString)
{
colorString += "m";
Console.Out.Write(colorString);
}
}
/// <summary>
/// Resets the color using ANSI escape codes
/// </summary>
internal static void ResetColorANSI()
{
Console.Out.Write("\x1b[m");
}
/// <summary>
/// Changes the foreground color to black if the foreground is the
/// same as the background. Changes the foreground to white if the

Просмотреть файл

@ -81,8 +81,8 @@ namespace Microsoft.Build.Logging
(
verbosity,
new WriteHandler(Console.Out.Write),
new ColorSetter(SetColor),
new ColorResetter(ResetColor)
new ColorSetter(BaseConsoleLogger.SetColor),
new ColorResetter(BaseConsoleLogger.ResetColor)
)
{
// do nothing
@ -120,6 +120,7 @@ namespace Microsoft.Build.Logging
{
bool useMPLogger = false;
bool disableConsoleColor = false;
bool forceConsoleColor = false;
if (!string.IsNullOrEmpty(_parameters))
{
string[] parameterComponents = _parameters.Split(BaseConsoleLogger.parameterDelimiters);
@ -139,11 +140,20 @@ namespace Microsoft.Build.Logging
{
disableConsoleColor = true;
}
if (0 == String.Compare(parameterComponents[param], "FORCECONSOLECOLOR", StringComparison.OrdinalIgnoreCase))
{
forceConsoleColor = true;
}
}
}
}
if (disableConsoleColor)
if (forceConsoleColor)
{
_colorSet = new ColorSetter(BaseConsoleLogger.SetColorANSI);
_colorReset = new ColorResetter(BaseConsoleLogger.ResetColorANSI);
}
else if (disableConsoleColor)
{
_colorSet = new ColorSetter(BaseConsoleLogger.DontSetColor);
_colorReset = new ColorResetter(BaseConsoleLogger.DontResetColor);
@ -477,66 +487,6 @@ namespace Microsoft.Build.Logging
_consoleLogger.CustomEventHandler(sender, e);
}
/// <summary>
/// Sets foreground color to color specified
/// </summary>
/// <param name="c">foreground color</param>
internal static void SetColor(ConsoleColor c)
{
try
{
Console.ForegroundColor =
TransformColor(c, BaseConsoleLogger.BackgroundColor);
}
catch (IOException)
{
// The color could not be set, no reason to crash
}
}
/// <summary>
/// Resets the color
/// </summary>
internal static void ResetColor()
{
try
{
Console.ResetColor();
}
catch (IOException)
{
// The color could not be reset, no reason to crash
}
}
/// <summary>
/// Changes the foreground color to black if the foreground is the
/// same as the background. Changes the foreground to white if the
/// background is black.
/// </summary>
/// <param name="foreground">foreground color for black</param>
/// <param name="background">current background</param>
private static ConsoleColor TransformColor(ConsoleColor foreground,
ConsoleColor background)
{
ConsoleColor result = foreground; //typically do nothing ...
if (foreground == background)
{
if (background != ConsoleColor.Black)
{
result = ConsoleColor.Black;
}
else
{
result = ConsoleColor.Gray;
}
}
return result;
}
#endregion
}
}

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -22,6 +19,18 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineConstants>$(DefineConstants);BUILD_ENGINE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DefineConstants>$(DefineConstants);BUILD_ENGINE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<DefineConstants>$(DefineConstants);BUILD_ENGINE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DefineConstants>$(DefineConstants);BUILD_ENGINE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<DefineConstants>$(DefineConstants);BUILD_ENGINE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
@ -210,6 +219,7 @@
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
<Compile Include="Definition\ProjectCollectionChangedEventArgs.cs" />
<Compile Include="Definition\ProjectImportPathMatch.cs" />
<Compile Include="Definition\ToolsetLocalReader.cs" />
<Compile Include="Evaluation\ItemsAndMetadataPair.cs" />
<Compile Include="Evaluation\MetadataReference.cs" />

Просмотреть файл

@ -0,0 +1,7 @@
[$RootKey$\RuntimeConfiguration\dependentAssembly\bindingRedirection\{0B54AF09-CDE4-40FD-9850-FFFED6E13680}]
"name"="Microsoft.Build"
"codeBase"="$BaseInstallDir$\MSBuild\15.0\Bin\Microsoft.Build.dll"
"publicKeyToken"="b03f5f7f11d50a3a"
"culture"="neutral"
"oldVersion"="0.0.0.0-99.9.9.9"
"newVersion"="15.1.0.0"

Просмотреть файл

@ -640,10 +640,10 @@ EndGlobal
/// <summary>
/// Generated project metaproj should declare its outputs for relay.
/// Here B depends on C
/// Here B depends on C (via solution dep only) and D (via ProjectReference only)
/// </summary>
/// <seealso href="https://github.com/Microsoft/msbuild/issues/69">
/// MSBuild should generate metaprojects that merge the outputs of the individual MSBuild invocations
/// MSBuild should generate metaprojects that relay the outputs of the individual MSBuild invocations
/// </seealso>
[Fact]
public void SolutionConfigurationWithDependenciesRelaysItsOutputs()
@ -660,20 +660,19 @@ Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-
EndProject
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}`
EndProject
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `D`, `D.csproj`, `{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}`
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = preSolution
{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.Build.0 = Release|Any CPU
{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU
{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -688,6 +687,12 @@ EndGlobal
<ComputedQuestion Include='What do you get if you multiply six by nine' />
</ItemGroup>
</Target>
<ItemGroup>
<ProjectReference Include='D.csproj'>
<Project>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</Project>
<Name>D</Name>
</ProjectReference>
</ItemGroup>
</Project>
";
const string projectCharlieFileContents =
@ -700,44 +705,85 @@ EndGlobal
</Target>
</Project>
";
const string projectDeltaFileContents =
@"
<Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
<PropertyGroup>
<ProjectGuid>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</ProjectGuid>
</PropertyGroup>
<Target Name='Build' Outputs='@(ComputedPunctuation)'>
<ItemGroup>
<ComputedPunctuation Include='!!!' />
</ItemGroup>
</Target>
</Project>
";
const string automaticProjectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='compile' xmlns='msbuildnamespace'>
<Target Name='compile'>
<MSBuild Projects='B.csproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='BravoProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' />
<MSBuild Projects='C.csproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='CharlieProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' />
<MSBuild Projects='B.csproj.metaproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='BravoMetaProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' />
<Error Condition=` '@(CharlieProjectOutputs);@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj must relay outputs' />
</Target>
<Target Name='compile'>
<!-- Build projects to get a baseline for their output -->
<MSBuild Projects='B.csproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='BravoProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' />
<MSBuild Projects='C.csproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='CharlieProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' />
<MSBuild Projects='D.csproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='DeltaProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='DeltaProjectOutputs: @(DeltaProjectOutputs)' />
<PropertyGroup>
<StringifiedBravoProjectOutputs>@(BravoProjectOutputs)</StringifiedBravoProjectOutputs>
<StringifiedCharlieProjectOutputs>@(CharlieProjectOutputs)</StringifiedCharlieProjectOutputs>
<StringifiedDeltaProjectOutputs>@(DeltaProjectOutputs)</StringifiedDeltaProjectOutputs>
</PropertyGroup>
<!-- Explicitly build the metaproject generated for B -->
<MSBuild Projects='B.csproj.metaproj' Targets='Build'>
<Output
TaskParameter='TargetOutputs'
ItemName='BravoMetaProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' />
<Error Condition=` '@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj outputs must match outputs of normal project build.' />
<!-- Build the solution as a whole (which will build the metaproj and return overall outputs) -->
<MSBuild Projects='MSBuildIssue.sln'>
<Output
TaskParameter='TargetOutputs'
ItemName='SolutionProjectOutputs' />
</MSBuild>
<Message Importance='high' Text='SolutionProjectOutputs: @(SolutionProjectOutputs)' />
<Error Condition=` '@(SolutionProjectOutputs->Count())' != '3' ` Text='Overall sln outputs must include outputs of each referenced project (there should be 3).' />
<Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedBravoProjectOutputs)'))' != 'true'` Text='Overall sln outputs must include outputs of normal project build of project B.' />
<Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedCharlieProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project C.' />
<Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedDeltaProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project D.' />
</Target>
</Project>";
#endregion
// arrange
var logger = new MockLogger();
var loggers = new List<ILogger>(1) { logger };
var solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("MSBuildIssue.sln", solutionFileContents);
ObjectModelHelpers.CreateFileInTempProjectDirectory("B.csproj", projectBravoFileContents);
ObjectModelHelpers.CreateFileInTempProjectDirectory("C.csproj", projectCharlieFileContents);
ObjectModelHelpers.CreateFileInTempProjectDirectory("D.csproj", projectDeltaFileContents);
var solution = new SolutionFile { FullPath = solutionFile };
solution.ParseSolutionFile();
// act
var instances = SolutionProjectGenerator.Generate(solution, null, null, new BuildEventContext(0, 0, 0, 0), null);
// assert
var projectBravoMetaProject = instances[1];
Assert.False(projectBravoMetaProject.Targets.Any(kvp => kvp.Value.Outputs.Equals("@()"))); // "The outputItem parameter can be null; the Target element should not have an Outputs attribute in that case."
// saves the in-memory metaproj to disk
@ -745,6 +791,8 @@ EndGlobal
var automaticProjectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("automatic.msbuild", automaticProjectFileContents);
var automaticProject = new Project(automaticProjectFile);
var buildResult = automaticProject.Build(loggers);
// NOTE: most of the actual assertions for this test are embedded in automaticProjectFileContents as <Error>s
Assert.True(buildResult, String.Join(Environment.NewLine, logger.Errors.Select(beea => beea.Message)));
}

Просмотреть файл

@ -86,7 +86,7 @@ namespace Microsoft.Build.UnitTests.Definition
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement("2.0").PropertyElements.GetElement("MSBuildBinPath").Value,
@"D:\windows\Microsoft.NET\Framework\v2.0.x86ret\");
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllMSBuildExtensionPathsSearchPaths.Count, 0);
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths.Count, 0);
}
/// <summary>
@ -185,7 +185,7 @@ namespace Microsoft.Build.UnitTests.Definition
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement("2.0").PropertyElements.GetElement("MSBuildBinPath").Value,
@"D:\windows\Microsoft.NET\Framework\v2.0.x86ret\");
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllMSBuildExtensionPathsSearchPaths.Count, 0);
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths.Count, 0);
}
#endregion
@ -520,7 +520,7 @@ namespace Microsoft.Build.UnitTests.Definition
<toolset toolsVersion=""2.0"">
<property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/>
<property name=""MSBuildToolsPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/>
<msbuildExtensionsPathSearchPaths>
<projectImportSearchPaths>
<searchPaths os=""windows"">
<property name=""MSBuildExtensionsPath"" value=""c:\foo""/>
<property name=""MSBuildExtensionsPath64"" value=""c:\foo64;c:\bar64""/>
@ -532,7 +532,7 @@ namespace Microsoft.Build.UnitTests.Definition
<searchPaths os=""unix"">
<property name=""MSBuildExtensionsPath"" value=""/tmp/bar""/>
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>"));
@ -548,8 +548,8 @@ namespace Microsoft.Build.UnitTests.Definition
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement("2.0").PropertyElements.GetElement("MSBuildBinPath").Value,
@"D:\windows\Microsoft.NET\Framework\v2.0.x86ret\");
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllMSBuildExtensionPathsSearchPaths.Count, 3);
var allPaths = msbuildToolsetSection.Toolsets.GetElement(0).AllMSBuildExtensionPathsSearchPaths;
Assert.Equal(msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths.Count, 3);
var allPaths = msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths;
Assert.Equal(allPaths.GetElement(0).OS, "windows");
Assert.Equal(allPaths.GetElement(0).PropertyElements.Count, 2);
Assert.Equal(allPaths.GetElement(0).PropertyElements.GetElement("MSBuildExtensionsPath").Value, @"c:\foo");
@ -570,24 +570,28 @@ namespace Microsoft.Build.UnitTests.Definition
string defaultOverrideToolsVersion = null;
string defaultToolsVersion = reader.ReadToolsets(toolsets, new PropertyDictionary<ProjectPropertyInstance>(), new PropertyDictionary<ProjectPropertyInstance>(), true, out msbuildOverrideTasksPath, out defaultOverrideToolsVersion);
Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> pathsTable = toolsets["2.0"].MSBuildExtensionsPathSearchPathsTable;
Dictionary<string, List<string>> pathsTable = toolsets["2.0"].ImportPropertySearchPathsTable;
#if XPLAT
if (NativeMethodsShared.IsWindows)
#endif
{
CheckPathsTable(pathsTable, MSBuildExtensionsPathReferenceKind.Default, new string[] {"c:\\foo"});
CheckPathsTable(pathsTable, MSBuildExtensionsPathReferenceKind.Path64, new string[] {"c:\\foo64", "c:\\bar64"});
CheckPathsTable(pathsTable, "MSBuildExtensionsPath", new string[] {"c:\\foo"});
CheckPathsTable(pathsTable, "MSBuildExtensionsPath64", new string[] {"c:\\foo64", "c:\\bar64"});
}
#if XPLAT
else if (NativeMethodsShared.IsOSX)
{
CheckPathsTable(pathsTable, MSBuildExtensionsPathReferenceKind.Default, new string[] {"/tmp/foo"});
CheckPathsTable(pathsTable, MSBuildExtensionsPathReferenceKind.Path32, new string[] {"/tmp/foo32", "/tmp/bar32"});
CheckPathsTable(pathsTable, ProjectImportPathMatch.Default, new string[] {"/tmp/foo"});
CheckPathsTable(pathsTable, ProjectImportPathMatch.Path32, new string[] {"/tmp/foo32", "/tmp/bar32"});
}
else
{
CheckPathsTable(pathsTable, MSBuildExtensionsPathReferenceKind.Default, new string[] {"/tmp/bar"});
CheckPathsTable(pathsTable, ProjectImportPathMatch.Default, new string[] {"/tmp/bar"});
}
#endif
}
private void CheckPathsTable(Dictionary<MSBuildExtensionsPathReferenceKind, IList<string>> pathsTable, MSBuildExtensionsPathReferenceKind kind, string[] expectedPaths)
private void CheckPathsTable(Dictionary<string, List<string>> pathsTable, string kind, string[] expectedPaths)
{
Assert.True(pathsTable.ContainsKey(kind));
var paths = pathsTable[kind];
@ -616,14 +620,14 @@ namespace Microsoft.Build.UnitTests.Definition
<toolset ToolsVersion=""2.0"">
<property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v3.5.x86ret\""/>
<msbuildExtensionsPathSearchPaths>
<projectImportSearchPaths>
<searchPaths os=""windows"">
<property name=""MSBuildExtensionsPath"" value=""c:\foo""/>
</searchPaths>
<searchPaths os=""windows"">
<property name=""MSBuildExtensionsPath"" value=""c:\bar""/>
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>"));
@ -652,12 +656,12 @@ namespace Microsoft.Build.UnitTests.Definition
<toolset ToolsVersion=""2.0"">
<property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v3.5.x86ret\""/>
<msbuildExtensionsPathSearchPaths>
<projectImportSearchPaths>
<searchPaths os=""windows"">
<property name=""MSBuildExtensionsPath"" value=""c:\foo""/>
<property name=""MSBuildExtensionsPath"" value=""c:\bar""/>
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>"));
@ -671,8 +675,7 @@ namespace Microsoft.Build.UnitTests.Definition
private ToolsetConfigurationReader GetStandardConfigurationReader()
{
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), new ReadApplicationConfiguration(
ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest));
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest);
}
#endregion

Просмотреть файл

@ -319,8 +319,7 @@ namespace Microsoft.Build.UnitTests.Definition
{
ToolsetConfigurationReaderTestHelper.WriteConfigFile(@"");
ToolsetReader reader = new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), new ReadApplicationConfiguration(
ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest));
ToolsetReader reader = new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest);
Dictionary<string, Toolset> values = new Dictionary<string, Toolset>(StringComparer.OrdinalIgnoreCase);
@ -2140,7 +2139,7 @@ namespace Microsoft.Build.UnitTests.Definition
Project project = projectCollection.LoadProject(projectPath);
string defaultExpected = "14.1";
string defaultExpected = "15.0";
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
defaultExpected = ObjectModelHelpers.MSBuildDefaultToolsVersion;
@ -2857,8 +2856,7 @@ namespace Microsoft.Build.UnitTests.Definition
#if FEATURE_SYSTEM_CONFIGURATION
private ToolsetConfigurationReader GetStandardConfigurationReader()
{
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), new ReadApplicationConfiguration(
ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest));
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest);
}
#endif
}

Просмотреть файл

@ -114,7 +114,11 @@ namespace Microsoft.Build.UnitTests.Definition
Dictionary<string, SubToolset> subToolsets = new Dictionary<string, SubToolset>(StringComparer.OrdinalIgnoreCase);
subToolsets.Add("dogfood", new SubToolset("dogfood", subToolsetProperties));
Toolset t = new Toolset("4.0", "c:\\bar", buildProperties, environmentProperties, globalProperties, subToolsets, "c:\\foo", "4.0");
Toolset t = new Toolset("4.0", "c:\\bar", buildProperties, environmentProperties, globalProperties,
subToolsets, "c:\\foo", "4.0", new Dictionary<string, List<string>>
{
["MSBuildExtensionsPath"] = new List<string> {@"c:\foo"}
});
((INodePacketTranslatable)t).Translate(TranslationHelpers.GetWriteTranslator());
Toolset t2 = Toolset.FactoryForDeserialization(TranslationHelpers.GetReadTranslator());
@ -150,11 +154,15 @@ namespace Microsoft.Build.UnitTests.Definition
}
else
{
Assert.True(false, string.Format("Sub-toolset {0} was lost in translation.", key));
Assert.True(false, $"Sub-toolset {key} was lost in translation.");
}
}
Assert.Equal(t.DefaultOverrideToolsVersion, t2.DefaultOverrideToolsVersion);
Assert.NotNull(t2.ImportPropertySearchPathsTable);
Assert.Equal(1, t2.ImportPropertySearchPathsTable.Count);
Assert.Equal(@"c:\foo", t2.ImportPropertySearchPathsTable["MSBuildExtensionsPath"][0]);
}
[Fact]

Просмотреть файл

@ -349,14 +349,6 @@ namespace Microsoft.Build.UnitTests.Evaluation
</Project>
";
string v2Folder = NativeMethodsShared.IsWindows
? @"D:\windows\Microsoft.NET\Framework\v2.0.x86ret"
: Path.Combine(NativeMethodsShared.FrameworkBasePath, "2.0");
string v4Folder = NativeMethodsShared.IsWindows
? @"D:\windows\Microsoft.NET\Framework\v4.0.x86ret"
: Path.Combine(NativeMethodsShared.FrameworkBasePath, "4.0");
var configFileContents = @"
<configuration>
<configSections>
@ -366,13 +358,13 @@ namespace Microsoft.Build.UnitTests.Evaluation
<toolset toolsVersion=""14.1"">
<property name=""MSBuildToolsPath"" value="".""/>
<property name=""MSBuildBinPath"" value=""" + /*v4Folder*/"." + @"""/>
<msbuildExtensionsPathSearchPaths>
<projectImportSearchPaths>
<searchPaths os=""" + NativeMethodsShared.GetOSNameForExtensionsPath() + @""">
<property name=""MSBuildExtensionsPath"" value=""{0}"" />
<property name=""MSBuildExtensionsPath32"" value=""{1}"" />
<property name=""MSBuildExtensionsPath64"" value=""{2}"" />
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>";
@ -423,6 +415,198 @@ namespace Microsoft.Build.UnitTests.Evaluation
}
}
// Fall-back path that has a property in it: $(FallbackExpandDir1)
[Fact]
public void ExpandExtensionsPathFallback()
{
string extnTargetsFileContentTemplate = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
<Target Name='FromExtn'>
<Message Text='Running FromExtn'/>
</Target>
<Import Project='$(MSBuildExtensionsPath)\\foo\\extn.proj' Condition=""Exists('$(MSBuildExtensionsPath)\foo\extn.proj')"" />
</Project>";
var configFileContents = @"
<configuration>
<configSections>
<section name=""msbuildToolsets"" type=""Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build"" />
</configSections>
<msbuildToolsets default=""14.1"">
<toolset toolsVersion=""14.1"">
<property name=""MSBuildToolsPath"" value="".""/>
<property name=""MSBuildBinPath"" value="".""/>
<projectImportSearchPaths>
<searchPaths os=""" + NativeMethodsShared.GetOSNameForExtensionsPath() + @""">
<property name=""MSBuildExtensionsPath"" value=""$(FallbackExpandDir1)"" />
</searchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>";
string extnDir1 = null;
string mainProjectPath = null;
try
{
extnDir1 = GetNewExtensionsPathAndCreateFile("extensions1", Path.Combine("foo", "extn.proj"),
extnTargetsFileContentTemplate);
mainProjectPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("main.proj",
GetMainTargetFileContent());
ToolsetConfigurationReaderTestHelper.WriteConfigFile(configFileContents);
var reader = GetStandardConfigurationReader();
var projectCollection = new ProjectCollection(new Dictionary<string, string> {["FallbackExpandDir1"] = extnDir1});
projectCollection.ResetToolsetsForTests(reader);
var logger = new MockLogger();
projectCollection.RegisterLogger(logger);
var project = projectCollection.LoadProject(mainProjectPath);
Assert.True(project.Build("Main"));
logger.AssertLogContains("Running FromExtn");
}
finally
{
FileUtilities.DeleteNoThrow(mainProjectPath);
FileUtilities.DeleteDirectoryNoThrow(extnDir1, true);
}
}
// Fall-back path that has a property in it: $(FallbackExpandDir1)
[Fact]
public void ExpandExtensionsPathFallbackInErrorMessage()
{
string extnTargetsFileContentTemplate = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
<Target Name='FromExtn'>
<Message Text='Running FromExtn'/>
</Target>
<Import Project='$(MSBuildExtensionsPath)\\foo\\extn2.proj' Condition=""Exists('$(MSBuildExtensionsPath)\foo\extn.proj')"" />
</Project>";
var configFileContents = @"
<configuration>
<configSections>
<section name=""msbuildToolsets"" type=""Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build"" />
</configSections>
<msbuildToolsets default=""14.1"">
<toolset toolsVersion=""14.1"">
<property name=""MSBuildToolsPath"" value="".""/>
<property name=""MSBuildBinPath"" value="".""/>
<projectImportSearchPaths>
<searchPaths os=""" + NativeMethodsShared.GetOSNameForExtensionsPath() + @""">
<property name=""MSBuildExtensionsPath"" value=""$(FallbackExpandDir1)"" />
</searchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>";
string extnDir1 = null;
string mainProjectPath = null;
try
{
extnDir1 = GetNewExtensionsPathAndCreateFile("extensions1", Path.Combine("foo", "extn.proj"),
extnTargetsFileContentTemplate);
mainProjectPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("main.proj",
GetMainTargetFileContent());
ToolsetConfigurationReaderTestHelper.WriteConfigFile(configFileContents);
var reader = GetStandardConfigurationReader();
var projectCollection = new ProjectCollection(new Dictionary<string, string> { ["FallbackExpandDir1"] = extnDir1 });
projectCollection.ResetToolsetsForTests(reader);
var logger = new MockLogger();
projectCollection.RegisterLogger(logger);
Assert.Throws<InvalidProjectFileException>(() => projectCollection.LoadProject(mainProjectPath));
// Expanded $(FallbackExpandDir) will appear in quotes in the log
logger.AssertLogContains("\"" + extnDir1 + "\"");
}
finally
{
FileUtilities.DeleteNoThrow(mainProjectPath);
FileUtilities.DeleteDirectoryNoThrow(extnDir1, true);
}
}
// Fall-back search path with custom variable
[Fact]
public void FallbackImportWithIndirectReference()
{
string mainTargetsFileContent = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
<PropertyGroup>
<VSToolsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v99</VSToolsPath>
</PropertyGroup>
<Import Project='$(VSToolsPath)\DNX\Microsoft.DNX.Props' Condition=""Exists('$(VSToolsPath)\DNX\Microsoft.DNX.Props')"" />
<Target Name='Main' DependsOnTargets='FromExtn' />
</Project>";
string extnTargetsFileContentTemplate = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
<Target Name='FromExtn'>
<Message Text='Running FromExtn'/>
</Target>
</Project>";
var configFileContents = @"
<configuration>
<configSections>
<section name=""msbuildToolsets"" type=""Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build"" />
</configSections>
<msbuildToolsets default=""14.1"">
<toolset toolsVersion=""14.1"">
<property name=""MSBuildToolsPath"" value="".""/>
<property name=""MSBuildBinPath"" value="".""/>
<projectImportSearchPaths>
<searchPaths os=""" + NativeMethodsShared.GetOSNameForExtensionsPath() + @""">
<property name=""MSBuildExtensionsPath"" value=""$(FallbackExpandDir1)"" />
<property name=""VSToolsPath"" value=""$(FallbackExpandDir1)\Microsoft\VisualStudio\v99"" />
</searchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>";
string extnDir1 = null;
string mainProjectPath = null;
try
{
extnDir1 = GetNewExtensionsPathAndCreateFile("extensions1", Path.Combine("Microsoft", "VisualStudio", "v99", "DNX", "Microsoft.DNX.Props"),
extnTargetsFileContentTemplate);
mainProjectPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("main.proj", mainTargetsFileContent);
ToolsetConfigurationReaderTestHelper.WriteConfigFile(configFileContents);
var reader = GetStandardConfigurationReader();
var projectCollection = new ProjectCollection(new Dictionary<string, string> { ["FallbackExpandDir1"] = extnDir1 });
projectCollection.ResetToolsetsForTests(reader);
var logger = new MockLogger();
projectCollection.RegisterLogger(logger);
var project = projectCollection.LoadProject(mainProjectPath);
Assert.True(project.Build("Main"));
logger.AssertLogContains("Running FromExtn");
}
finally
{
FileUtilities.DeleteNoThrow(mainProjectPath);
FileUtilities.DeleteDirectoryNoThrow(extnDir1, true);
}
}
void CreateAndBuildProjectForImportFromExtensionsPath(string extnPathPropertyName, Action<Project, MockLogger> action)
{
string extnDir1 = null, extnDir2 = null, mainProjectPath = null;
@ -484,7 +668,7 @@ namespace Microsoft.Build.UnitTests.Evaluation
{
string combinedExtnDirs = extnDirs != null ? String.Join(";", extnDirs) : String.Empty;
var configFilePath = ToolsetConfigurationReaderTestHelper.WriteConfigFile(@"
ToolsetConfigurationReaderTestHelper.WriteConfigFile(@"
<configuration>
<configSections>
<section name=""msbuildToolsets"" type=""Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build"" />
@ -493,11 +677,11 @@ namespace Microsoft.Build.UnitTests.Evaluation
<toolset toolsVersion=""14.1"">
<property name=""MSBuildToolsPath"" value=""."" />
<property name=""MSBuildBinPath"" value=""."" />
<msbuildExtensionsPathSearchPaths>
<projectImportSearchPaths>
<searchPaths os=""" + NativeMethodsShared.GetOSNameForExtensionsPath() + @""">
<property name=""" + extnPathPropertyName + @""" value=""" + combinedExtnDirs + @""" />
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>");
@ -565,8 +749,7 @@ namespace Microsoft.Build.UnitTests.Evaluation
private ToolsetConfigurationReader GetStandardConfigurationReader()
{
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), new ReadApplicationConfiguration(
ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest));
return new ToolsetConfigurationReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest);
}
}
}

Просмотреть файл

@ -0,0 +1,509 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Collections;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
using Microsoft.Build.Execution;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.Build.UnitTests
{
public class ExpressionTest : IDisposable
{
private readonly ITestOutputHelper output;
private static readonly string[] FilesWithExistenceChecks = { "a", "a;b", "a'b", ";", "'" };
private readonly Expander<ProjectPropertyInstance, ProjectItemInstance> _expander;
public static readonly IEnumerable<string[]> TrueTests = new []
{
"true or (SHOULDNOTEVALTHIS)", // short circuit
"(true and false) or true",
"false or true or false",
"(true) and (true)",
"false or !false",
"($(a) or true)",
"('$(c)'==1 and (!false))",
"@(z -> '%(filename).z', '$')=='xxx.z$yyy.z'",
"@(w -> '%(definingprojectname).barproj') == 'foo.barproj'",
"false or (false or (false or (false or (false or (true)))))",
"!(true and false)",
"$(and)=='and'",
"0x1==1.0",
"0xa==10",
"0<0.1",
"+4>-4",
"'-$(c)'==-1",
"$(a)==faLse",
"$(a)==oFF",
"$(a)==no",
"$(a)!=true",
"$(b)== True",
"$(b)==on",
"$(b)==yes",
"$(b)!=1",
"$(c)==1",
"$(d)=='xxx'",
"$(d)==$(e)",
"$(d)=='$(e)'",
"@(y)==$(d)",
"'@(z)'=='xxx;yyy'",
"$(a)==$(a)",
"'1'=='1'",
"'1'==1",
"1\n==1",
"1\t==\t\r\n1",
"123=='0123.0'",
"123==123",
"123==0123",
"123==0123.0",
"123!=0123.01",
"1.2.3<=1.2.3.0",
"12.23.34==12.23.34",
"0.8.0.0<8.0.0",
"1.1.2>1.0.1.2",
"8.1>8.0.16.23",
"8.0.0>=8",
"6<=6.0.0.1",
"7>6.8.2",
"4<5.9.9135.4",
"3!=3.0.0",
"1.2.3.4.5.6.7==1.2.3.4.5.6.7",
"00==0",
"0==0.0",
"1\n\t==1",
"+4==4",
"44==+44.0 and -44==-44.0",
"false==no",
"true==yes",
"true==!false",
"yes!=no",
"false!=1",
"$(c)>0",
"!$(a)",
"$(b)",
"($(d)==$(e))",
"!true==false",
"a_a==a_a",
"a_a=='a_a'",
"_a== _a",
"@(y -> '%(filename)')=='xxx'",
"@(z -> '%(filename)', '!')=='xxx!yyy'",
"'xxx!yyy'==@(z -> '%(filename)', '!')",
"'$(a)'==(false)",
"('$(a)'==(false))",
"1>0",
"2<=2",
"2<=3",
"1>=1",
"1>=-1",
"-1==-1",
"-1 < 0",
"(1==1)and('a'=='a')",
"(true) and ($(a)==off)",
"(true) and ($(d)==xxx)",
"(false) or($(d)==xxx)",
"!(false)and!(false)",
"'and'=='AND'",
"$(d)=='XxX'",
"true or true or false",
"false or true or !true or'1'",
"$(a) or $(b)",
"$(a) or true",
"!!true",
"'$(e)1@(y)'=='xxx1xxx'",
"0x11==17",
"0x01a==26",
"0xa==0x0A",
"@(x)",
"'%77'=='w'",
"'%zz'=='%zz'",
"true or 1",
"true==!false",
"(!(true))=='off'",
"@(w)>0",
"1<=@(w)",
"%(culture)=='FRENCH'",
"'%(culture) fries' == 'FRENCH FRIES' ",
@"'%(HintPath)' == ''",
@"%(HintPath) != 'c:\myassemblies\foo.dll'",
"exists('a')",
"exists(a)",
"exists('a%3bb')", /* semicolon */
"exists('a%27b')", /* apostrophe */
"exists($(a_escapedsemi_b))",
"exists('$(a_escapedsemi_b)')",
"exists($(a_escapedapos_b))",
"exists('$(a_escapedapos_b)')",
"exists($(a_apos_b))",
"exists('$(a_apos_b)')",
"exists(@(v))",
"exists('@(v)')",
"exists('%3b')",
"exists('%27')",
"exists('@(v);@(nonexistent)')",
@"HASTRAILINGSLASH('foo\')",
@"!HasTrailingSlash('foo')",
@"HasTrailingSlash('foo/')",
@"HasTrailingSlash($(has_trailing_slash))",
"'59264.59264' == '59264.59264'",
"1" + new String('0', 500) + "==" + "1" + new String('0', 500), /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='" + "1" + new String('0', 500) + "'" /* too big for double, eval as string */
}.Select(s => new[] {s});
public static readonly IEnumerable<string[]> FalseTests = new [] {
"false and SHOULDNOTEVALTHIS", // short circuit
"$(a)!=no",
"$(b)==1.1",
"$(c)==$(a)",
"$(d)!=$(e)",
"!$(b)",
"false or false or false",
"false and !((true and false))",
"on and off",
"(true) and (false)",
"false or (false or (false or (false or (false or (false)))))",
"!$(b)and true",
"1==a",
"!($(d)==$(e))",
"$(a) and true",
"true==1",
"false==0",
"(!(true))=='x'",
"oops==false",
"oops==!false",
"%(culture) == 'english'",
"'%(culture) fries' == 'english fries' ",
@"'%(HintPath)' == 'c:\myassemblies\foo.dll'",
@"%(HintPath) == 'c:\myassemblies\foo.dll'",
"exists('')",
"exists(' ')",
"exists($(nonexistent))", // DDB #141195
"exists('$(nonexistent)')", // DDB #141195
"exists(@(nonexistent))", // DDB #141195
"exists('@(nonexistent)')", // DDB #141195
"exists('\t')",
"exists('@(u)')",
"exists('$(foo_apos_foo)')",
"!exists('a')",
"!!!exists(a)",
"exists('|||||')",
@"hastrailingslash('foo')",
@"hastrailingslash('')",
@"HasTrailingSlash($(nonexistent))",
"'59264.59264' == '59264.59265'",
"1.2.0==1.2",
"$(f)!=$(f)",
"1.3.5.8>1.3.6.8",
"0.8.0.0>=1.0",
"8.0.0<=8.0",
"8.1.2<8",
"1" + new String('0', 500) + "==2", /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='2'", /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='01" + new String('0', 500) + "'" /* too big for double, eval as string */
}.Select(s => new[] { s });
public static readonly IEnumerable<object[]> ErrorTests = new [] {
"$",
"$(",
"$()",
"@",
"@(",
"@()",
"%",
"%(",
"%()",
"exists",
"exists(",
"exists()",
"exists( )",
"exists(,)",
"@(x->'",
"@(x->''",
"@(x-",
"@(x->'x','",
"@(x->'x',''",
"@(x->'x','')",
"-1>x",
"%00",
"\n",
"\t",
"+-1==1",
"1==-+1",
"1==+0xa",
"!$(c)",
"'a'==('a'=='a')",
"'a'!=('a'=='a')",
"('a'=='a')!=a",
"('a'=='a')==a",
"!'x'",
"!'$(d)'",
"ab#==ab#",
"#!=#",
"$(d)$(e)=='xxxxxx'",
"1=1=1",
"'a'=='a'=='a'",
"1 > 'x'",
"x1<=1",
"1<=x",
"1>x",
"x<x",
"@(x)<x",
"x>x",
"x>=x",
"x<=x",
"x>1",
"x>=1",
"1>=x",
"@(y)<=1",
"1<=@(z)",
"1>$(d)",
"$(c)@(y)>1",
"'$(c)@(y)'>1",
"$(d)>=1",
"1>=$(b)",
"1> =0",
"or true",
"1 and",
"and",
"or",
"not",
"not true",
"()",
"(a)",
"!",
"or=or",
"1==",
"1= =1",
"=",
"'true",
"'false''",
"'a'=='a",
"('a'=='a'",
"('a'=='a'))",
"'a'=='a')",
"!and",
"@(a)@(x)!=1",
"@(a) @(x)!=1",
"$(a==off",
"=='x'",
"==",
"!0",
">",
"true!=false==",
"true!=false==true",
"()",
"!1",
"1==(2",
"$(a)==x>1==2",
"'a'>'a'",
"0",
"$(a)>0",
"!$(e)",
"1<=1<=1",
"true $(and) true",
"--1==1",
"$(and)==and",
"!@#$%^&*",
"-($(c))==-1",
"a==b or $(d)",
"false or $()",
"$(d) or true",
"%(Culture) or true",
"@(nonexistent) and true",
"$(nonexistent) and true",
"@(nonexistent)",
"$(nonexistent)",
"@(z) and true",
"@() and true",
"@()",
"$()",
"1",
"1 or true",
"false or 1",
"1 and true",
"true and 1",
"!1",
"false or !1",
"false or 'aa'",
"true blah",
"existsX",
"!",
"nonexistentfunction('xyz')",
"exists('a;b')", /* non scalar */
"exists(@(z))",
"exists('@(z)')",
"exists($(a_semi_b))",
"exists('$(a_semi_b)')",
"exists(@(v)x)",
"exists(@(v)$(nonexistent))",
"exists('@(v)$(a)')",
"exists(|||||)",
"HasTrailingSlash(a,'b')",
"HasTrailingSlash(,,)",
"1.2.3==1,2,3"
}.Select(s => new[] { s });
/// <summary>
/// Set up expression tests by creating files for existence checks.
/// </summary>
public ExpressionTest(ITestOutputHelper output)
{
this.output = output;
ItemDictionary<ProjectItemInstance> itemBag = new ItemDictionary<ProjectItemInstance>();
// Dummy project instance to own the items.
ProjectRootElement xml = ProjectRootElement.Create();
xml.FullPath = @"c:\abc\foo.proj";
ProjectInstance parentProject = new ProjectInstance(xml);
itemBag.Add(new ProjectItemInstance(parentProject, "u", "a'b;c", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "v", "a", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "w", "1", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "x", "true", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "y", "xxx", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "z", "xxx", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "z", "yyy", parentProject.FullPath));
PropertyDictionary<ProjectPropertyInstance> propertyBag = new PropertyDictionary<ProjectPropertyInstance>();
propertyBag.Set(ProjectPropertyInstance.Create("a", "no"));
propertyBag.Set(ProjectPropertyInstance.Create("b", "true"));
propertyBag.Set(ProjectPropertyInstance.Create("c", "1"));
propertyBag.Set(ProjectPropertyInstance.Create("d", "xxx"));
propertyBag.Set(ProjectPropertyInstance.Create("e", "xxx"));
propertyBag.Set(ProjectPropertyInstance.Create("f", "1.9.5"));
propertyBag.Set(ProjectPropertyInstance.Create("and", "and"));
propertyBag.Set(ProjectPropertyInstance.Create("a_semi_b", "a;b"));
propertyBag.Set(ProjectPropertyInstance.Create("a_apos_b", "a'b"));
propertyBag.Set(ProjectPropertyInstance.Create("foo_apos_foo", "foo'foo"));
propertyBag.Set(ProjectPropertyInstance.Create("a_escapedsemi_b", "a%3bb"));
propertyBag.Set(ProjectPropertyInstance.Create("a_escapedapos_b", "a%27b"));
propertyBag.Set(ProjectPropertyInstance.Create("has_trailing_slash", @"foo\"));
Dictionary<string, string> metadataDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
metadataDictionary["Culture"] = "french";
StringMetadataTable itemMetadata = new StringMetadataTable(metadataDictionary);
_expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(propertyBag, itemBag, itemMetadata);
foreach (string file in FilesWithExistenceChecks)
{
using (StreamWriter sw = File.CreateText(file)) {; }
}
}
/// <summary>
/// Clean up files created for these tests.
/// </summary>
public void Dispose()
{
foreach (string file in FilesWithExistenceChecks)
{
if (File.Exists(file)) File.Delete(file);
}
}
/// <summary>
/// A whole bunch of conditionals that should be true
/// (many coincidentally like existing QA tests) to give breadth coverage.
/// Please add more cases as they arise.
/// </summary>
[Theory]
[MemberData(nameof(TrueTests))]
public void EvaluateAVarietyOfTrueExpressions(string expression)
{
Parser p = new Parser();
GenericExpressionNode tree;
tree = p.Parse(expression, ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
expression,
_expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
Assert.True(tree.Evaluate(state), "expected true from '" + expression + "'");
}
/// <summary>
/// A whole bunch of conditionals that should be false
/// (many coincidentally like existing QA tests) to give breadth coverage.
/// Please add more cases as they arise.
/// </summary>
[Theory]
[MemberData(nameof(FalseTests))]
public void EvaluateAVarietyOfFalseExpressions(string expression)
{
Parser p = new Parser();
GenericExpressionNode tree;
tree = p.Parse(expression, ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
expression,
_expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
Assert.False(tree.Evaluate(state), "expected false from '" + expression + "' and got true");
}
/// <summary>
/// A whole bunch of conditionals that should produce errors
/// (many coincidentally like existing QA tests) to give breadth coverage.
/// Please add more cases as they arise.
/// </summary>
[Theory]
[MemberData(nameof(ErrorTests))]
public void EvaluateAVarietyOfErrorExpressions(string expression)
{
// If an expression is invalid,
// - Parse may throw, or
// - Evaluate may throw, or
// - Evaluate may return false causing its caller EvaluateCondition to throw
bool caughtException = false;
try
{
Parser p = new Parser();
var tree = p.Parse(expression, ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
expression,
_expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
var value = tree.Evaluate(state);
}
catch (InvalidProjectFileException ex)
{
output.WriteLine(expression + " caused '" + ex.Message + "'");
caughtException = true;
}
Assert.True(caughtException,
"expected '" + expression + "' to not parse or not be evaluated");
}
}
}

Просмотреть файл

@ -36,471 +36,6 @@ namespace Microsoft.Build.UnitTests
AssertParseEvaluate(p, "no", expander, false);
}
/// <summary>
/// A whole bunch of conditionals, that should be true, false, or error
/// (many coincidentally like existing QA tests) to give breadth coverage.
/// Please add more cases as they arise.
/// </summary>
[Fact]
public void EvaluateAVarietyOfExpressions()
{
string[] files = { "a", "a;b", "a'b", ";", "'" };
try
{
foreach (string file in files)
{
using (StreamWriter sw = File.CreateText(file)) {; }
}
Parser p = new Parser();
GenericExpressionNode tree;
ItemDictionary<ProjectItemInstance> itemBag = new ItemDictionary<ProjectItemInstance>();
// Dummy project instance to own the items.
ProjectRootElement xml = ProjectRootElement.Create();
xml.FullPath = @"c:\abc\foo.proj";
ProjectInstance parentProject = new ProjectInstance(xml);
itemBag.Add(new ProjectItemInstance(parentProject, "u", "a'b;c", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "v", "a", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "w", "1", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "x", "true", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "y", "xxx", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "z", "xxx", parentProject.FullPath));
itemBag.Add(new ProjectItemInstance(parentProject, "z", "yyy", parentProject.FullPath));
PropertyDictionary<ProjectPropertyInstance> propertyBag = new PropertyDictionary<ProjectPropertyInstance>();
propertyBag.Set(ProjectPropertyInstance.Create("a", "no"));
propertyBag.Set(ProjectPropertyInstance.Create("b", "true"));
propertyBag.Set(ProjectPropertyInstance.Create("c", "1"));
propertyBag.Set(ProjectPropertyInstance.Create("d", "xxx"));
propertyBag.Set(ProjectPropertyInstance.Create("e", "xxx"));
propertyBag.Set(ProjectPropertyInstance.Create("f", "1.9.5"));
propertyBag.Set(ProjectPropertyInstance.Create("and", "and"));
propertyBag.Set(ProjectPropertyInstance.Create("a_semi_b", "a;b"));
propertyBag.Set(ProjectPropertyInstance.Create("a_apos_b", "a'b"));
propertyBag.Set(ProjectPropertyInstance.Create("foo_apos_foo", "foo'foo"));
propertyBag.Set(ProjectPropertyInstance.Create("a_escapedsemi_b", "a%3bb"));
propertyBag.Set(ProjectPropertyInstance.Create("a_escapedapos_b", "a%27b"));
propertyBag.Set(ProjectPropertyInstance.Create("has_trailing_slash", @"foo\"));
Dictionary<string, string> metadataDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
metadataDictionary["Culture"] = "french";
StringMetadataTable itemMetadata = new StringMetadataTable(metadataDictionary);
Expander<ProjectPropertyInstance, ProjectItemInstance> expander =
new Expander<ProjectPropertyInstance, ProjectItemInstance>(propertyBag, itemBag, itemMetadata);
string[] trueTests = {
"true or (SHOULDNOTEVALTHIS)", // short circuit
"(true and false) or true",
"false or true or false",
"(true) and (true)",
"false or !false",
"($(a) or true)",
"('$(c)'==1 and (!false))",
"@(z -> '%(filename).z', '$')=='xxx.z$yyy.z'",
"@(w -> '%(definingprojectname).barproj') == 'foo.barproj'",
"false or (false or (false or (false or (false or (true)))))",
"!(true and false)",
"$(and)=='and'",
"0x1==1.0",
"0xa==10",
"0<0.1",
"+4>-4",
"'-$(c)'==-1",
"$(a)==faLse",
"$(a)==oFF",
"$(a)==no",
"$(a)!=true",
"$(b)== True",
"$(b)==on",
"$(b)==yes",
"$(b)!=1",
"$(c)==1",
"$(d)=='xxx'",
"$(d)==$(e)",
"$(d)=='$(e)'",
"@(y)==$(d)",
"'@(z)'=='xxx;yyy'",
"$(a)==$(a)",
"'1'=='1'",
"'1'==1",
"1\n==1",
"1\t==\t\r\n1",
"123=='0123.0'",
"123==123",
"123==0123",
"123==0123.0",
"123!=0123.01",
"1.2.3<=1.2.3.0",
"12.23.34==12.23.34",
"0.8.0.0<8.0.0",
"1.1.2>1.0.1.2",
"8.1>8.0.16.23",
"8.0.0>=8",
"6<=6.0.0.1",
"7>6.8.2",
"4<5.9.9135.4",
"3!=3.0.0",
"1.2.3.4.5.6.7==1.2.3.4.5.6.7",
"00==0",
"0==0.0",
"1\n\t==1",
"+4==4",
"44==+44.0 and -44==-44.0",
"false==no",
"true==yes",
"true==!false",
"yes!=no",
"false!=1",
"$(c)>0",
"!$(a)",
"$(b)",
"($(d)==$(e))",
"!true==false",
"a_a==a_a",
"a_a=='a_a'",
"_a== _a",
"@(y -> '%(filename)')=='xxx'",
"@(z -> '%(filename)', '!')=='xxx!yyy'",
"'xxx!yyy'==@(z -> '%(filename)', '!')",
"'$(a)'==(false)",
"('$(a)'==(false))",
"1>0",
"2<=2",
"2<=3",
"1>=1",
"1>=-1",
"-1==-1",
"-1 < 0",
"(1==1)and('a'=='a')",
"(true) and ($(a)==off)",
"(true) and ($(d)==xxx)",
"(false) or($(d)==xxx)",
"!(false)and!(false)",
"'and'=='AND'",
"$(d)=='XxX'",
"true or true or false",
"false or true or !true or'1'",
"$(a) or $(b)",
"$(a) or true",
"!!true",
"'$(e)1@(y)'=='xxx1xxx'",
"0x11==17",
"0x01a==26",
"0xa==0x0A",
"@(x)",
"'%77'=='w'",
"'%zz'=='%zz'",
"true or 1",
"true==!false",
"(!(true))=='off'",
"@(w)>0",
"1<=@(w)",
"%(culture)=='FRENCH'",
"'%(culture) fries' == 'FRENCH FRIES' ",
@"'%(HintPath)' == ''",
@"%(HintPath) != 'c:\myassemblies\foo.dll'",
"exists('a')",
"exists(a)",
"exists('a%3bb')", /* semicolon */
"exists('a%27b')", /* apostrophe */
"exists($(a_escapedsemi_b))",
"exists('$(a_escapedsemi_b)')",
"exists($(a_escapedapos_b))",
"exists('$(a_escapedapos_b)')",
"exists($(a_apos_b))",
"exists('$(a_apos_b)')",
"exists(@(v))",
"exists('@(v)')",
"exists('%3b')",
"exists('%27')",
"exists('@(v);@(nonexistent)')",
@"HASTRAILINGSLASH('foo\')",
@"!HasTrailingSlash('foo')",
@"HasTrailingSlash('foo/')",
@"HasTrailingSlash($(has_trailing_slash))",
"'59264.59264' == '59264.59264'",
"1" + new String('0', 500) + "==" + "1" + new String('0', 500), /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='" + "1" + new String('0', 500) + "'" /* too big for double, eval as string */
};
string[] falseTests = {
"false and SHOULDNOTEVALTHIS", // short circuit
"$(a)!=no",
"$(b)==1.1",
"$(c)==$(a)",
"$(d)!=$(e)",
"!$(b)",
"false or false or false",
"false and !((true and false))",
"on and off",
"(true) and (false)",
"false or (false or (false or (false or (false or (false)))))",
"!$(b)and true",
"1==a",
"!($(d)==$(e))",
"$(a) and true",
"true==1",
"false==0",
"(!(true))=='x'",
"oops==false",
"oops==!false",
"%(culture) == 'english'",
"'%(culture) fries' == 'english fries' ",
@"'%(HintPath)' == 'c:\myassemblies\foo.dll'",
@"%(HintPath) == 'c:\myassemblies\foo.dll'",
"exists('')",
"exists(' ')",
"exists($(nonexistent))", // DDB #141195
"exists('$(nonexistent)')", // DDB #141195
"exists(@(nonexistent))", // DDB #141195
"exists('@(nonexistent)')", // DDB #141195
"exists('\t')",
"exists('@(u)')",
"exists('$(foo_apos_foo)')",
"!exists('a')",
"!!!exists(a)",
"exists('|||||')",
@"hastrailingslash('foo')",
@"hastrailingslash('')",
@"HasTrailingSlash($(nonexistent))",
"'59264.59264' == '59264.59265'",
"1.2.0==1.2",
"$(f)!=$(f)",
"1.3.5.8>1.3.6.8",
"0.8.0.0>=1.0",
"8.0.0<=8.0",
"8.1.2<8",
"1" + new String('0', 500) + "==2", /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='2'", /* too big for double, eval as string */
"'1" + new String('0', 500) + "'=='01" + new String('0', 500) + "'" /* too big for double, eval as string */
};
string[] errorTests = {
"$",
"$(",
"$()",
"@",
"@(",
"@()",
"%",
"%(",
"%()",
"exists",
"exists(",
"exists()",
"exists( )",
"exists(,)",
"@(x->'",
"@(x->''",
"@(x-",
"@(x->'x','",
"@(x->'x',''",
"@(x->'x','')",
"-1>x",
"%00",
"\n",
"\t",
"+-1==1",
"1==-+1",
"1==+0xa",
"!$(c)",
"'a'==('a'=='a')",
"'a'!=('a'=='a')",
"('a'=='a')!=a",
"('a'=='a')==a",
"!'x'",
"!'$(d)'",
"ab#==ab#",
"#!=#",
"$(d)$(e)=='xxxxxx'",
"1=1=1",
"'a'=='a'=='a'",
"1 > 'x'",
"x1<=1",
"1<=x",
"1>x",
"x<x",
"@(x)<x",
"x>x",
"x>=x",
"x<=x",
"x>1",
"x>=1",
"1>=x",
"@(y)<=1",
"1<=@(z)",
"1>$(d)",
"$(c)@(y)>1",
"'$(c)@(y)'>1",
"$(d)>=1",
"1>=$(b)",
"1> =0",
"or true",
"1 and",
"and",
"or",
"not",
"not true",
"()",
"(a)",
"!",
"or=or",
"1==",
"1= =1",
"=",
"'true",
"'false''",
"'a'=='a",
"('a'=='a'",
"('a'=='a'))",
"'a'=='a')",
"!and",
"@(a)@(x)!=1",
"@(a) @(x)!=1",
"$(a==off",
"=='x'",
"==",
"!0",
">",
"true!=false==",
"true!=false==true",
"()",
"!1",
"1==(2",
"$(a)==x>1==2",
"'a'>'a'",
"0",
"$(a)>0",
"!$(e)",
"1<=1<=1",
"true $(and) true",
"--1==1",
"$(and)==and",
"!@#$%^&*",
"-($(c))==-1",
"a==b or $(d)",
"false or $()",
"$(d) or true",
"%(Culture) or true",
"@(nonexistent) and true",
"$(nonexistent) and true",
"@(nonexistent)",
"$(nonexistent)",
"@(z) and true",
"@() and true",
"@()",
"$()",
"1",
"1 or true",
"false or 1",
"1 and true",
"true and 1",
"!1",
"false or !1",
"false or 'aa'",
"true blah",
"existsX",
"!",
"nonexistentfunction('xyz')",
"exists('a;b')", /* non scalar */
"exists(@(z))",
"exists('@(z)')",
"exists($(a_semi_b))",
"exists('$(a_semi_b)')",
"exists(@(v)x)",
"exists(@(v)$(nonexistent))",
"exists('@(v)$(a)')",
"exists(|||||)",
"HasTrailingSlash(a,'b')",
"HasTrailingSlash(,,)",
"1.2.3==1,2,3"
};
for (int i = 0; i < trueTests.GetLength(0); i++)
{
tree = p.Parse(trueTests[i], ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
trueTests[i],
expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
Assert.True(tree.Evaluate(state), "expected true from '" + trueTests[i] + "'");
}
for (int i = 0; i < falseTests.GetLength(0); i++)
{
tree = p.Parse(falseTests[i], ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
falseTests[i],
expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
Assert.False(tree.Evaluate(state), "expected false from '" + falseTests[i] + "' and got true");
}
for (int i = 0; i < errorTests.GetLength(0); i++)
{
// It seems that if an expression is invalid,
// - Parse may throw, or
// - Evaluate may throw, or
// - Evaluate may return false causing its caller EvaluateCondition to throw
bool success = true;
bool caughtException = false;
bool value;
try
{
tree = p.Parse(errorTests[i], ParserOptions.AllowAll, ElementLocation.EmptyLocation);
ConditionEvaluator.IConditionEvaluationState state =
new ConditionEvaluator.ConditionEvaluationState<ProjectPropertyInstance, ProjectItemInstance>
(
errorTests[i],
expander,
ExpanderOptions.ExpandAll,
null,
Directory.GetCurrentDirectory(),
ElementLocation.EmptyLocation
);
value = tree.Evaluate(state);
if (!success) Console.WriteLine(errorTests[i] + " caused Evaluate to return false");
}
catch (InvalidProjectFileException ex)
{
Console.WriteLine(errorTests[i] + " caused '" + ex.Message + "'");
caughtException = true;
}
Assert.True((success == false || caughtException == true), "expected '" + errorTests[i] + "' to not parse or not be evaluated");
}
}
finally
{
foreach (string file in files)
{
if (File.Exists(file)) File.Delete(file);
}
}
}
/// <summary>
/// </summary>
[Fact]

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.props"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -14,14 +11,14 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Include="..\..\Shared\FxCopExclusions\Microsoft.Build.Shared.Suppressions.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
@ -157,6 +154,7 @@
<Compile Include="Evaluation\ProjectRootElementCache_Tests.cs" />
<Compile Include="Evaluation\ProjectStringCache_Tests.cs" />
<Compile Include="EventArgsFormatting_Tests.cs" />
<Compile Include="ExpressionTreeExpression_Tests.cs" />
<Compile Include="ExpressionTree_Tests.cs" />
<Compile Include="FileLogger_Tests.cs" />
<Compile Include="HashTableUtility_Tests.cs" />
@ -228,8 +226,5 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.targets"/>
</Project>

Просмотреть файл

@ -216,6 +216,28 @@ namespace Microsoft.Build.UnitTests
Assert.True(fExceptionCaught);
}
[Fact]
public void ItemFuncParseTest()
{
Console.WriteLine("ItemFuncParseTest()");
Parser p = new Parser();
GenericExpressionNode tree;
tree = p.Parse("@(item->foo('ab'))",
ParserOptions.AllowProperties | ParserOptions.AllowItemLists, _elementLocation);
Assert.IsType<StringExpressionNode>(tree);
Assert.Equal("@(item->foo('ab'))", tree.GetUnexpandedValue(null));
tree = p.Parse("!@(item->foo())",
ParserOptions.AllowProperties | ParserOptions.AllowItemLists, _elementLocation);
Assert.IsType<NotExpressionNode>(tree);
tree = p.Parse("(@(item->foo('ab')) and @(item->foo('bc')))",
ParserOptions.AllowProperties | ParserOptions.AllowItemLists, _elementLocation);
Assert.IsType<AndExpressionNode>(tree);
}
[Fact]
public void MetadataParseTest()
{

Просмотреть файл

@ -618,7 +618,7 @@ namespace Microsoft.Build.UnitTests
Project project = ObjectModelHelpers.CreateInMemoryProject(
@"
<Project DefaultTargets=`Build` ToolsVersion=`14.1` xmlns=`msbuildnamespace`>
<Project DefaultTargets=`Build` ToolsVersion=`15.0` xmlns=`msbuildnamespace`>
<PropertyGroup>
<OutputPath>" + outputPath + @"</OutputPath>
<AssemblyName>MyAssembly</AssemblyName>

Просмотреть файл

@ -16,14 +16,14 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Condition="'$(NetCoreBuild)' == 'true'" Include="..\..\Shared\Compat\SafeHandleZeroOrMinusOneIsInvalid.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>

Просмотреть файл

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="dogfood" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildProjectReferences>true</BuildProjectReferences>
</PropertyGroup>
<Import Project="$(_NTDRIVE)$(_NTROOT)\tools\Microsoft.DevDiv.Settings.targets"/>
<ItemGroup>

Просмотреть файл

@ -48,7 +48,9 @@ namespace Microsoft.Build.CommandLine
OldOM,
#endif
DistributedFileLogger,
#if FEATURE_MSBUILD_DEBUGGER
Debugger,
#endif
DetailedSummary,
#if DEBUG
WaitForDebugger,
@ -225,8 +227,9 @@ namespace Microsoft.Build.CommandLine
new ParameterlessSwitchInfo( new string[] { "oldom" }, ParameterlessSwitch.OldOM, null, null ),
#endif
new ParameterlessSwitchInfo( new string[] { "distributedfilelogger", "dfl" }, ParameterlessSwitch.DistributedFileLogger, null, null ),
#if FEATURE_MSBUILD_DEBUGGER
new ParameterlessSwitchInfo( new string[] { "debug", "d" }, ParameterlessSwitch.Debugger, null, "DebuggerEnabled"),
#endif
new ParameterlessSwitchInfo( new string[] { "detailedsummary", "ds" }, ParameterlessSwitch.DetailedSummary, null , null ),
#if DEBUG
new ParameterlessSwitchInfo( new string[] { "waitfordebugger", "wfd" }, ParameterlessSwitch.WaitForDebugger, null , null ),
@ -461,10 +464,19 @@ namespace Microsoft.Build.CommandLine
{
// initialize its parameter storage
_parameterizedSwitches[(int)parameterizedSwitch].parameters = new ArrayList();
}
// save the switch text
_parameterizedSwitches[(int)parameterizedSwitch].commandLineArg = commandLineArg;
// save the switch text
_parameterizedSwitches[(int)parameterizedSwitch].commandLineArg = commandLineArg;
}
else
{
// append the switch text
_parameterizedSwitches[(int)parameterizedSwitch].commandLineArg = string.Concat(
_parameterizedSwitches[(int)parameterizedSwitch].commandLineArg,
" ",
commandLineArg
);
}
// check if the switch has multiple parameters
if (multipleParametersAllowed)
@ -861,7 +873,7 @@ namespace Microsoft.Build.CommandLine
}
}
#region Flag Lightup Support
#region Flag Lightup Support
/// <summary>
/// Read a lightup key from either HKLM or HKCU depending on what is passed in root.
/// The key may either be a string, in which case it needs to be like "true" or "false"
@ -945,6 +957,6 @@ namespace Microsoft.Build.CommandLine
parameterlessSwitch.lightUpKeyResult = ReadLightupBool(parameterlessSwitch.lightUpKey);
return parameterlessSwitch.lightUpKeyResult;
}
#endregion
#endregion
}
}

Просмотреть файл

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -13,6 +10,7 @@
<RootNamespace>Microsoft.Build.CommandLine</RootNamespace>
<AssemblyName>MSBuild</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>MSBuild.exe.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(NetCoreBuild)' == 'true'">
<StartAction Condition="'$(StartAction)'==''">Program</StartAction>
@ -20,33 +18,19 @@
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup>
<ApplicationManifest>MSBuild.exe.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|x86'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|x86'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|x64'" />
<ItemGroup Condition="$(TargetFrameworkIdentifier) != '.NETFramework'">
<Compile Include="..\Shared\Compat\SerializableAttribute.cs">
<Link>Compat\SerializableAttribute.cs</Link>
@ -230,8 +214,5 @@
<None Include="MSBuild.exe.manifest" />
<None Include="project.json" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.targets" />
</Project>

Просмотреть файл

@ -303,6 +303,8 @@ Copyright (C) Microsoft Corporation. All rights reserved.
EnableMPLogging--Enable the multiprocessor logging
style even when running in non-multiprocessor
mode. This logging style is on by default.
ForceConsoleColor--Use ANSI console colors even if
console does not support it
Verbosity--overrides the /verbosity setting for this
logger.
Example:

Просмотреть файл

@ -760,7 +760,7 @@ namespace Microsoft.Build.UnitTests
// purposes of testing the SetParameterizedSwitch() method, it doesn't matter
Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/verbosity:\"diag\";minimal", "\"diag\";minimal", true, true));
Assert.Equal("/verbosity:\"diag\";minimal", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity));
Assert.Equal("/v:q /verbosity:\"diag\";minimal", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity));
Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Verbosity));
parameters = switches[CommandLineSwitches.ParameterizedSwitch.Verbosity];
@ -803,7 +803,7 @@ namespace Microsoft.Build.UnitTests
// more fake/missing parameters
Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:A,\"\";B", "A,\"\";B", true, true));
Assert.Equal("/t:A,\"\";B", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target));
Assert.Equal("/t:\" /t:A,\"\";B", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target));
Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target));
parameters = switches[CommandLineSwitches.ParameterizedSwitch.Target];
@ -845,7 +845,7 @@ namespace Microsoft.Build.UnitTests
// parameters, but for testing purposes this is fine
Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/LOGGER:\"\",asm;\"p,a;r\"", "\"\",asm;\"p,a;r\"", true, false));
Assert.Equal("/LOGGER:\"\",asm;\"p,a;r\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger));
Assert.Equal("/l:\" /LOGGER:\"\",asm;\"p,a;r\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger));
Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger));
parameters = switches[CommandLineSwitches.ParameterizedSwitch.Logger];

Просмотреть файл

@ -14,14 +14,14 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<Compile Include="..\..\Shared\FxCopExclusions\Microsoft.Build.Shared.Suppressions.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
@ -99,8 +99,5 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\..\dir.targets"/>
</Project>

Просмотреть файл

@ -1917,7 +1917,9 @@ namespace Microsoft.Build.CommandLine
preprocessWriter = ProcessPreprocessSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Preprocess]);
}
#if FEATURE_MSBUILD_DEBUGGER
debugger = commandLineSwitches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Debugger);
#endif
detailedSummary = commandLineSwitches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.DetailedSummary);
// figure out which loggers are going to listen to build events
@ -2131,7 +2133,7 @@ namespace Microsoft.Build.CommandLine
#if !STANDALONEBUILD
else
{
StartLocalNodeOldOM(nodeNumber);
StartLocalNodeOldOM(nodeModeNumber);
}
#endif
}
@ -2231,7 +2233,7 @@ namespace Microsoft.Build.CommandLine
{
foreach (string s in potentialSolutionFiles)
{
if (s.EndsWith("~", StringComparison.CurrentCultureIgnoreCase))
if (!FileUtilities.IsSolutionFilename(s))
{
extensionsToIgnore.Add(Path.GetExtension(s));
}

Просмотреть файл

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- Microsoft.Build.Engine instead of Microsoft.Build here because a task run under Microsoft.Build may load Microsoft.Build.Engine, which will attempt to read this section. -->
<section name="msbuildToolsets" type="Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build, Version=14.1.0.0, Culture=neutral" />
<section name="msbuildToolsets" type="Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<DisableFXClosureWalk enabled="true" />
@ -13,37 +12,71 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Conversion.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Tasks.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Utilities.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="14.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<!-- To define one or more new toolsets, add an 'msbuildToolsets' element in this file. -->
<msbuildToolsets default="14.1">
<toolset toolsVersion="14.1">
<msbuildToolsets default="15.0">
<toolset toolsVersion="15.0">
<property name="MSBuildToolsPath" value="." />
<msbuildExtensionsPathSearchPaths>
<property name="MSBuildToolsPath32" value="." />
<!--<property name="FrameworkSDKRoot" value="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)" />-->
<property name="MSBuildRuntimeVersion" value="4.0.30319" />
<property name="MSBuildFrameworkToolsPath" value="$(SystemRoot)\Microsoft.NET\Framework\v$(MSBuildRuntimeVersion)\" />
<property name="MSBuildFrameworkToolsPath32" value="$(SystemRoot)\Microsoft.NET\Framework\v$(MSBuildRuntimeVersion)\" />
<property name="MSBuildFrameworkToolsRoot" value="$(SystemRoot)\Microsoft.NET\Framework\" />
<property name="SDK35ToolsPath" value="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx35Tools-x86@InstallationFolder)" />
<property name="SDK40ToolsPath" value="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools-x86@InstallationFolder)" />
<!-- TODO: hacks (remove ..\ )-->
<property name="VSInstallRoot" value="$(MSBuildToolsPath)\..\..\.." />
<property name="MSBuildToolsRoot" value="$(VSInstallRoot)\MSBuild" />
<property name="MSBuildExtensionsPath" value="$(VSInstallRoot)\MSBuild" />
<property name="MSBuildExtensionsPath32" value="$(VSInstallRoot)\MSBuild" />
<property name="VCTargetsPath" value="$(VSInstallRoot)\Common7\IDE\VC\VCTargets" />
<property name="FrameworkSDKRoot" value="$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v10.0A\" />
<projectImportSearchPaths>
<searchPaths os="windows">
<property name="MSBuildExtensionsPath" value="$(MSBuildProgramFiles32)\MSBuild"/>
<property name="MSBuildExtensionsPath32" value="$(MSBuildProgramFiles32)\MSBuild"/>
<property name="MSBuildExtensionsPath64" value="$(MSBuildProgramFiles32)\MSBuild"/>
<property name="VSToolsPath" value="$(MSBuildProgramFiles32)\MSBuild\Microsoft\VisualStudio\v$(VisualStudioVersion)"/>
</searchPaths>
</projectImportSearchPaths>
</toolset>
<toolset toolsVersion="14.0">
<property name="MSBuildToolsPath" value="." />
</toolset>
<toolset toolsVersion="12.0">
<property name="MSBuildToolsPath" value="." />
</toolset>
<toolset toolsVersion="4.0">
<property name="MSBuildToolsPath" value="." />
<projectImportSearchPaths>
<searchPaths os="osx">
<property name="MSBuildExtensionsPath" value="/Library/Frameworks/Mono.framework/External/xbuild/"/>
<property name="MSBuildExtensionsPath32" value="/Library/Frameworks/Mono.framework/External/xbuild/"/>
<property name="MSBuildExtensionsPath64" value="/Library/Frameworks/Mono.framework/External/xbuild/"/>
</searchPaths>
</msbuildExtensionsPathSearchPaths>
</projectImportSearchPaths>
</toolset>
</msbuildToolsets>
</configuration>

Просмотреть файл

@ -16,7 +16,7 @@ namespace Microsoft.Build.Tasks
/// Hashtable of other dependency files.
/// Key is filename and value is DependencyFile.
/// </summary>
private Hashtable _dependencies = new Hashtable();
private Hashtable dependencies = new Hashtable();
/// <summary>
/// Look up a dependency file. Return null if its not there.
@ -25,7 +25,7 @@ namespace Microsoft.Build.Tasks
/// <returns></returns>
internal DependencyFile GetDependencyFile(string filename)
{
return (DependencyFile)_dependencies[filename];
return (DependencyFile)dependencies[filename];
}
@ -36,7 +36,7 @@ namespace Microsoft.Build.Tasks
/// <returns></returns>
internal void AddDependencyFile(string filename, DependencyFile file)
{
_dependencies[filename] = file;
dependencies[filename] = file;
}
/// <summary>
@ -46,7 +46,7 @@ namespace Microsoft.Build.Tasks
/// <returns></returns>
internal void RemoveDependencyFile(string filename)
{
_dependencies.Remove(filename);
dependencies.Remove(filename);
}
/// <summary>
@ -54,7 +54,7 @@ namespace Microsoft.Build.Tasks
/// </summary>
internal void Clear()
{
_dependencies.Clear();
dependencies.Clear();
}
}
}

Просмотреть файл

@ -33,16 +33,20 @@ namespace Microsoft.Build.Tasks
// Console-based output uses the current system OEM code page by default. Note that we should not use Console.OutputEncoding
// here since processes we run don't really have much to do with our console window (and also Console.OutputEncoding
// doesn't return the OEM code page if the running application that hosts MSBuild is not a console application).
// Note: 8/12/15 - Changed encoding to use UTF8 when OS version is greater than or equal to 6.1 (Windows 7)
_standardOutputEncoding = GetEncodingWithOsFallback();
_standardErrorEncoding = GetEncodingWithOsFallback();
// If the cmd file contains non-ANSI characters encoding may change.
_standardOutputEncoding = EncodingUtilities.CurrentSystemOemEncoding;
_standardErrorEncoding = EncodingUtilities.CurrentSystemOemEncoding;
}
#endregion
#region Fields
// Are the ecodings for StdErr and StdOut streams valid
private const string UseUtf8Always = "ALWAYS";
private const string UseUtf8Never = "NEVER";
private const string UseUtf8Detect = "DETECT";
// Are the encodings for StdErr and StdOut streams valid
private bool _encodingParametersValid = true;
private string _workingDirectory;
private ITaskItem[] _outputs;
@ -70,7 +74,7 @@ namespace Microsoft.Build.Tasks
/// Enable the pipe of the standard out to an item (StandardOutput).
/// </summary>
/// <Remarks>
/// Even thought this is called a pipe, it is infact a Tee. Use StandardOutputImportance to adjust the visibility of the stdout.
/// Even thought this is called a pipe, it is in fact a Tee. Use StandardOutputImportance to adjust the visibility of the stdout.
/// </Remarks>
public bool ConsoleToMSBuild { get; set; }
@ -123,6 +127,14 @@ namespace Microsoft.Build.Tasks
get { return _standardErrorEncoding; }
}
/// <summary>
/// Whether or not to use UTF8 encoding for the cmd file and console window.
/// Values: Always, Never, Detect
/// If set to Detect, the current code page will be used unless it cannot represent
/// the Command string. In that case, UTF-8 is used.
/// </summary>
public string UseUtf8Encoding { get; set; }
/// <summary>
/// Project visible property specifying the encoding of the captured task standard output stream
/// </summary>
@ -191,6 +203,8 @@ namespace Microsoft.Build.Tasks
/// </summary>
private void CreateTemporaryBatchFile()
{
var encoding = BatchFileEncoding();
// Temporary file with the extension .Exec.bat
_batchFile = FileUtilities.GetTemporaryFile(".exec.cmd");
bool isUnix = Path.DirectorySeparatorChar == '/';
@ -201,7 +215,8 @@ namespace Microsoft.Build.Tasks
// just the OEM version.
// See http://www.microsoft.com/globaldev/getWR/steps/wrg_codepage.mspx for a discussion of ANSI vs OEM
// Note: 8/12/15 - Switched to use UTF8 on OS newer than 6.1 (Windows 7)
using (StreamWriter sw = FileUtilities.OpenWrite(_batchFile, false, GetEncodingWithOsFallback()))
// Note: 1/12/16 - Only use UTF8 when we detect we need to or the user specifies 'Always'
using (StreamWriter sw = FileUtilities.OpenWrite(_batchFile, false, encoding))
{
if (!isUnix)
{
@ -220,12 +235,21 @@ namespace Microsoft.Build.Tasks
sw.WriteLine("set errorlevel=dummy");
sw.WriteLine("set errorlevel=");
// set the console to use the stream writer's encoding
// We may need to change the code page and console encoding.
if (encoding.CodePage != EncodingUtilities.CurrentSystemOemEncoding.CodePage)
{
// Output to nul so we don't change output and logs.
sw.WriteLine(string.Format(@"%SystemRoot%\System32\chcp.com {0}>nul", sw.Encoding.CodePage));
sw.WriteLine(string.Format(@"%SystemRoot%\System32\chcp.com {0}>nul", encoding.CodePage));
// Ensure that the console encoding is correct.
_standardOutputEncoding = encoding;
_standardErrorEncoding = encoding;
}
// if the working directory is a UNC path, bracket the exec command with pushd and popd, because pushd
// automatically maps the network path to a drive letter, and then popd disconnects it
// automatically maps the network path to a drive letter, and then popd disconnects it.
// This is required because Cmd.exe does not support UNC names as the current directory:
// https://support.microsoft.com/en-us/kb/156276
if (workingDirectoryIsUNC)
{
sw.WriteLine("pushd " + _workingDirectory);
@ -618,29 +642,81 @@ namespace Microsoft.Build.Tasks
private static readonly Encoding s_utf8WithoutBom = new UTF8Encoding(false);
/// <summary>
/// Get encoding based on OS. This will fall back to previous behavior on Windows before Windows 7.
/// If the OS is greater than or equal to Windows 7, UTF8 encoding will be used for the cmd file.
/// On unices, use ASCII.
/// Find the encoding for the batch file.
/// </summary>
/// <remarks>UTF8 w/o BOM is used because cmd.exe does not like a BOM in a .cmd file.</remarks>
/// <returns>Encoding to use</returns>
private Encoding GetEncodingWithOsFallback()
/// <remarks>
/// The "best" encoding is the current OEM encoding, unless it's not capable of representing
/// the characters we plan to put in the file. If it isn't, we can fall back to UTF-8.
///
/// Why not always UTF-8? Because tools don't always handle it well. See
/// https://github.com/Microsoft/msbuild/issues/397
/// </remarks>
private Encoding BatchFileEncoding()
{
#if FEATURE_OSVERSION
if (!NativeMethodsShared.IsWindows)
{
return s_utf8WithoutBom;
}
var defaultEncoding = EncodingUtilities.CurrentSystemOemEncoding;
string useUtf8 = string.IsNullOrEmpty(UseUtf8Encoding) ? UseUtf8Detect : UseUtf8Encoding;
// Windows 7 (6.1) or greater
// UTF8 is only supposed in Windows 7 (6.1) or greater.
var windows7 = new Version(6, 1);
return Environment.OSVersion.Version >= windows7
? s_utf8WithoutBom
: EncodingUtilities.CurrentSystemOemEncoding;
if (Environment.OSVersion.Version < windows7)
{
useUtf8 = UseUtf8Never;
}
switch (useUtf8.ToUpperInvariant())
{
case UseUtf8Always:
return s_utf8WithoutBom;
case UseUtf8Never:
return EncodingUtilities.CurrentSystemOemEncoding;
default:
return CanEncodeString(defaultEncoding.CodePage, Command + WorkingDirectory)
? defaultEncoding
: s_utf8WithoutBom;
}
#else
return s_utf8WithoutBom;
#endif
}
/// <summary>
/// Checks to see if a string can be encoded in a specified code page.
/// </summary>
/// <remarks>Internal for testing purposes.</remarks>
/// <param name="codePage">Code page for encoding.</param>
/// <param name="stringToEncode">String to encode.</param>
/// <returns>True if the string can be encoded in the specified code page.</returns>
internal static bool CanEncodeString(int codePage, string stringToEncode)
{
// We have a System.String that contains some characters. Get a lossless representation
// in byte-array form.
var unicodeEncoding = new UnicodeEncoding();
var unicodeBytes = unicodeEncoding.GetBytes(stringToEncode);
// Create an Encoding using the desired code page, but throws if there's a
// character that can't be represented.
var systemEncoding = Encoding.GetEncoding(codePage, EncoderFallback.ExceptionFallback,
DecoderFallback.ExceptionFallback);
try
{
var oemBytes = Encoding.Convert(unicodeEncoding, systemEncoding, unicodeBytes);
// If Convert didn't throw, we can represent everything in the desired encoding.
return true;
}
catch (EncoderFallbackException)
{
// If a fallback encoding was attempted, we need to go to Unicode.
return false;
}
}
}
}

Просмотреть файл

@ -21,6 +21,11 @@ namespace Microsoft.Build.Tasks
public class GetReferenceAssemblyPaths : TaskExtension
{
#region Data
/// <summary>
/// Environment variable name for the override error on missing reference assembly directory.
/// </summary>
private const string WARNONNOREFERENCEASSEMBLYDIRECTORY = "MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY";
/// <summary>
/// This is the sentinel assembly for .NET FX 3.5 SP1
/// Used to determine if SP1 of 3.5 is installed
@ -43,7 +48,7 @@ namespace Microsoft.Build.Tasks
private IList<string> _tfmPathsNoProfile;
/// <summary>
/// Target framework moniker string passd into the task
/// Target framework moniker string passed into the task
/// </summary>
private string _targetFrameworkMoniker;
@ -243,7 +248,7 @@ namespace Microsoft.Build.Tasks
_tfmPathsNoProfile = GetPaths(_rootPath, monikerWithNoProfile);
}
// The path with out the profile is just the referecne assembly paths.
// The path with out the profile is just the reference assembly paths.
if (!targetingProfile)
{
_tfmPathsNoProfile = _tfmPaths;
@ -283,10 +288,22 @@ namespace Microsoft.Build.Tasks
pathsToReturn = ToolLocationHelper.GetPathToReferenceAssemblies(rootPath, frameworkmoniker);
}
// No reference assembly paths could be found, log a warning as there could be future errors which may be confusing because of this.
// No reference assembly paths could be found, log an error so an invalid build will not be produced.
// 1/26/16: Note this was changed from a warning to an error (see GitHub #173). Also added the escape hatch
// (set MSBUILDWARNONNOREFERENCEASSEMBLYDIRECTORY = 1) in case this causes issues.
// TODO: This should be removed for Dev15
if (pathsToReturn.Count == 0)
{
Log.LogWarningWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString());
var warn = Environment.GetEnvironmentVariable(WARNONNOREFERENCEASSEMBLYDIRECTORY);
if (string.Equals(warn, "1", StringComparison.Ordinal))
{
Log.LogWarningWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString());
}
else
{
Log.LogErrorWithCodeFromResources("GetReferenceAssemblyPaths.NoReferenceAssemblyDirectoryFound", frameworkmoniker.ToString());
}
}
return pathsToReturn;

Просмотреть файл

@ -703,9 +703,7 @@ namespace Microsoft.Build.Tasks.Deployment.ManifestUtilities
private static void SignPEFile(X509Certificate2 cert, System.Uri timestampUrl, string path, System.Resources.ResourceManager resources, bool useSha256)
{
if (GetPathToTool() == null) throw new ApplicationException(resources.GetString("SecurityUtil.SigntoolNotFound"));
ProcessStartInfo startInfo = new ProcessStartInfo(GetPathToTool(), GetCommandLineParameters(cert.Thumbprint, timestampUrl, path, useSha256));
ProcessStartInfo startInfo = new ProcessStartInfo(GetPathToTool(resources), GetCommandLineParameters(cert.Thumbprint, timestampUrl, path, useSha256));
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
@ -760,7 +758,7 @@ namespace Microsoft.Build.Tasks.Deployment.ManifestUtilities
return commandLine.ToString();
}
internal static string GetPathToTool()
internal static string GetPathToTool(System.Resources.ResourceManager resources)
{
#pragma warning disable 618 // Disabling warning on using internal ToolLocationHelper API. At some point we should migrate this.
string toolPath = ToolLocationHelper.GetPathToWindowsSdkFile(ToolName, TargetDotNetFrameworkVersion.VersionLatest, VisualStudioVersion.VersionLatest);
@ -771,7 +769,7 @@ namespace Microsoft.Build.Tasks.Deployment.ManifestUtilities
if (toolPath == null)
toolPath = Path.Combine(Directory.GetCurrentDirectory(), ToolName);
if (!File.Exists(toolPath))
toolPath = null;
throw new ApplicationException(String.Format(CultureInfo.CurrentCulture, resources.GetString("SecurityUtil.SigntoolNotFound"), toolPath));
return toolPath;
#pragma warning restore 618
}

Просмотреть файл

@ -145,7 +145,7 @@
<value xml:space="preserve">Warning while signing {0}. {1}</value>
</data>
<data name="SecurityUtil.SigntoolNotFound">
<value xml:space="preserve">SignTool.exe not found.</value>
<value xml:space="preserve">SignTool.exe was not found at path {0}.</value>
</data>
<data name="SecurityUtil.TimestampUrlNotFound">
<value xml:space="preserve">Timestamp URL server name or address could not be resolved.</value>

Просмотреть файл

@ -0,0 +1,7 @@
[$RootKey$\RuntimeConfiguration\dependentAssembly\bindingRedirection\{5BDA9EB8-561A-405C-A482-2CD328059DEA}]
"name"="Microsoft.Build.Tasks.Core"
"codeBase"="$BaseInstallDir$\MSBuild\15.0\Bin\Microsoft.Build.Tasks.Core.dll"
"publicKeyToken"="b03f5f7f11d50a3a"
"culture"="neutral"
"oldVersion"="0.0.0.0-99.9.9.9"
"newVersion"="15.1.0.0"

Просмотреть файл

@ -16,14 +16,14 @@
<CopyNuGetImplementations>true</CopyNuGetImplementations>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-MONO|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-MONO|AnyCPU'" />
<ItemGroup>
<EmbeddedResource Include="system.design\system.design.txt">
<Type>Resx</Type>
@ -930,8 +930,5 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<!--
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" Condition="!$(Configuration.EndsWith('MONO'))"/>
-->
<Import Project="..\dir.targets" />
</Project>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше