Team Build overrides the output directories that are specified in the individual project files, and thus places all build output at $(BinariesRoot)\$(Platfom)\$(Configuration)\
Yes, you need to set the SkipDropBuild property to true inside your tfsbuild.proj file.
No it is not possible now. We are working on it.
Unfortunately Team Build can not use the relative output paths specified in each project properties. We wanted to use TargetOutputs item which captures the relative path of output assembly (based on project settings). We can not use it because –
There is no easy way to do it but I do have this workaround –
Expected actions from the user -
<Target Name="CoreClean"
DependsOnTargets="$(CoreCleanDependsOn)"
Condition=" '$(SkipClean)'!='true' ">
<!-- Clean for desktop build -->
<MSBuild
Condition="'$(IsDesktopBuild)'=='true'"
Projects="$(MSBuildProjectFile)"
Targets="RunCoreCleanWithConfiguration"
Properties="RunCodeAnalysis=$(RunCodeAnalysis); BinariesRoot=$(BinariesRoot);FxCopDir=$(FxCopDir);Platform=%(ConfigurationToBuild.PlatformToBuild);Flavor=%(ConfigurationToBuild.FlavorToBuild); " />
<!-- Clean SolutionRoot only for end to end build -->
<RemoveDir
Condition="Exists('$(SolutionRoot)') and '$(IsDesktopBuild)'!='true'"
Directories="$(SolutionRoot)" />
Condition="Exists('$(BinariesRoot)') and '$(IsDesktopBuild)'!='true'"
Directories="$(BinariesRoot)" />
Condition="Exists('$(TestResultsRoot)') and '$(IsDesktopBuild)'!='true'"
Directories="$(TestResultsRoot)" />
</Target>
<Target Name="RunCoreCleanWithConfiguration" >
<!-- OutDirForClean for not Any CPU -->
<CreateItem
Condition=" '$(Platform)'!='Any CPU' "
Include="$(BinariesRoot)\$(Platform)\$(Flavor)\" >
<Output TaskParameter="Include" ItemName="OutDirForClean" />
</CreateItem>
<!-- OutDirForClean for Any CPU -->
Condition=" '$(Platform)'=='Any CPU' "
Include="$(BinariesRoot)\$(Flavor)\" >
<!-- OutDir - to ensure we have absolute path as property -->
<CreateProperty Value="%(OutDirForClean.FullPath)" >
<Output TaskParameter="Value" PropertyName="OutDir" />
</CreateProperty>
<!-- Call MSBuild /t:Clean for desktop build -->
Projects="@(SolutionToBuild)"
Properties="Configuration=$(Flavor);Platform=$(Platform);RunCodeAnalysis=$(RunCodeAnalysis);SkipInvalidConfigurations=true;FxCopDir=$(FxCopDir);OutDir=$(OutDir)%(SolutionToBuild.OutputFolder)\"
Targets="Clean" />
<Target Name="CoreCompile"
DependsOnTargets="$(CoreCompileDependsOn)">
<MakeDir
Directories="$(BinariesRoot)"
Condition="!Exists('$(BinariesRoot)')" />
<TeamBuildMessage
Tag="Configuration"
Condition=" '$(IsDesktopBuild)'!='true' "
Value="%(ConfigurationToBuild.FlavorToBuild)" />
Tag="Platform"
Value="%(ConfigurationToBuild.PlatformToBuild)" />
<!-- Need proper location of build type otherwise logger fail (file not in enlistment)-->
Condition="'$(IsDesktopBuild)'!='true' "
Projects="$(SolutionRoot)\TeamBuildTypes\$(BuildType)\TfsBuild.proj"
Targets="RunCoreCompileWithConfiguration"
Properties="Platform=%(ConfigurationToBuild.PlatformToBuild);Flavor=%(ConfigurationToBuild.FlavorToBuild);RunCodeAnalysis=$(RunCodeAnalysis);BinariesRoot=$(BinariesRoot);FxCopDir=$(FxCopDir);TeamBuildConstants=$(TeamBuildConstants);SolutionRoot=$(SolutionRoot)" />
<!-- Destop build, need this because $(Buildtype) not defined in desktop scenario-->
Condition="'$(IsDesktopBuild)'=='true' "
<OnError ExecuteTargets="OnBuildBreak;" />
<Target Name="RunCoreCompileWithConfiguration" >
<!-- OutDirForCompile for not Any CPU -->
<Output TaskParameter="Include" ItemName="OutDirForCompile" />
<!-- OutDirForCompile for Any CPU -->
<!-- OutDir property - This is to ensure we have absolute path as property -->
<CreateProperty Value="%(OutDirForCompile.FullPath)" >
<!-- First part of VCOverride file -->
<CreateProperty Value="%3C?xml version=%221.0%22?%3E%0D%0A%3CVisualStudioPropertySheet ProjectType=%22Visual C++%22 Version=%228.00%22 Name=%22Team Build Overrides%22 OutputDirectory=%22$(OutDir)%22%3E%0D%0A" >
<Output TaskParameter="Value"
PropertyName="VCOverridesString1"/>
<!-- Third part of VCOverride file -->
<CreateProperty Value="%3C/VisualStudioPropertySheet%3E" >
PropertyName="VCOverridesString3"/>
<!-- RunCodeAnalysis option -->
<CreateProperty
Condition=" '$(RunCodeAnalysis)'=='Always' "
Value="RunCodeAnalysis=true" >
PropertyName="CodeAnalysisOption" />
<!— 2nd part of VCOverride file when RunCodeAnalysis is always -->
Value="%09%3CTool Name=%22VCCLCompilerTool%22 EnablePREfast=%22true%22 /%3E%0D%0A%09%3CTool Name=%22VCFxCopTool%22 EnableFxCop=%22true%22 /%3E%0D%0A" >
PropertyName="VCOverridesString2"/>
Condition=" '$(RunCodeAnalysis)'=='Never' "
Value="RunCodeAnalysis=false" >
<!-- Second part of VCOverride file when RunCodeAnalysis is never -->
Value="%09%3CTool Name=%22VCCLCompilerTool%22 EnablePREfast=%22false%22 /%3E%0D%0A%09%3CTool Name=%22VCFxCopTool%22 EnableFxCop=%22false%22 /%3E%0D%0A" >
<!-- ReferencePath option -->
Condition=" '@(AdditionalReferencePath)'!='' "
Value="$(OutDir);@(AdditionalReferencePath)" >
<Output TaskParameter="Value" PropertyName="ReferencePath" />
Condition=" '@(AdditionalReferencePath)'=='' "
Value="$(OutDir)" >
<!-- Generate VCOverride file for C++ projects -->
<WriteLinesToFile
File="TFSBuild.vsprops"
Lines="$(VCOverridesString1)$(VCOverridesString2)$(AdditionalVCOverrides)$(VCOverridesString3)"
Overwrite="true" />
<!-- Build using MSBuild task -->
Condition=" '@(SolutionToBuild)'!='' "
Properties="Configuration=$(Flavor);Platform=$(Platform);SkipInvalidConfigurations=true;VCBuildOverride=$(MSBuildProjectDirectory)\TFSBuild.vsprops;FxCopDir=$(FxCopDir);OutDir=$(OutDir)%(SolutionToBuild.OutputFolder)\;ReferencePath=$(ReferencePath);TeamBuildConstants=$(TeamBuildConstants);$(CodeAnalysisOption)"
Targets="Build" />
<!-- Specify SolutionToPublish ItemGroup if you have ClickOnce based solutions or projects that you want to publish. The task below will generate manifest and deployment package. -->
Condition=" '@(SolutionToPublish)'!='' "
Projects="@(SolutionToPublish)"
Properties="Configuration=$(Flavor);Platform=$(Platform);SkipInvalidConfigurations=true;VCBuildOverride=$(MSBuildProjectDirectory)\TFSBuild.vsprops;FxCopDir=$(FxCopDir);OutDir=$(OutDir)%(SolutionToPublish.OutputFolder)\;PublishDir=$(OutDir)%(SolutionToPublish.OutputFolder)\;ReferencePath=$(ReferencePath);TeamBuildConstants=$(TeamBuildConstants);$(CodeAnalysisOption)"
Targets="Publish" />
<ItemGroup>
<SolutionToBuild Include="$(SolutionRoot)\ClassLibrary1\ClassLibrary1.sln">
<OutputFolder>Lib</OutputFolder>
</SolutionToBuild>
<SolutionToBuild Include="$(SolutionRoot)\ConsoleApplication1\ConsoleApplication1.sln">
<OutputFolder>App</OutputFolder>
</ItemGroup>
Please note the OutputFolder attribute will point to the sub folder under BinariesRoot\<platform>\<configuration>. For example in the above scenario we are interested in building for AnyCPU|Debug, then the output assemblies will be @ $(BinariesRoot)\Debug\Lib\Classlibrary1.dll, $(BinariesRoot)\Debug\App\ClassApplication1.exe.
It is not advisable to change the structure to BinariesRoot\<subfolder>\<platform>\<configuration>.
Advantages of this approach
Disadvantages of this approach
Tested scenarios