зеркало из https://github.com/dotnet/msbuild.git
Merge remote-tracking branch 'Microsoft/master' into xplat
This commit is contained in:
Коммит
0a3eb9b25c
|
@ -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" />
|
||||
|
|
13
build.cmd
13
build.cmd
|
@ -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%
|
||||
|
|
25
build.proj
25
build.proj
|
@ -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 "$(SourceDir)MSBuild.sln"" 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>
|
||||
|
|
|
@ -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>
|
||||
|
|
18
netci.groovy
18
netci.groovy
|
@ -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) "$(NuGetProjectJsonFile)""/>
|
||||
|
||||
<!-- <Exec Condition="Exists('$(NuGetProjectJsonFile)')"
|
||||
Command="$(DotnetToolCommand) publish -f dnxcore50 -r $(NuGetRuntimeIdentifier) -o $(ToolPackagesDir) "$(NuGetProjectJsonFile)""
|
||||
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>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче