6
votes

I'm using Pre-/Post-build events in my VS2012 project files to perform build tasks. This works perfectly fine locally, but I have an issue running it from our TFS 2012 Build Server.

Locally the $(TargetDir) for each project is set to its own /bin folder.

On the build server however this is set to a single /bin folder outside of the solution root folder in which it consolidates all the binaries that were build.

This is not at all what I want!
I just want the build server to behave the same way as my VS2012 build does.
There doesn't seem to be any setting in the build template that allows me to alter this.

Can anyone tell me how I can make the build server output its binaries to a separate /bin folder for each project?

(FYI, the build server is set to build the .sln file, not some additional MSBuild script.)

2

2 Answers

7
votes

TFS and Visual Studio both use msbuild to build your solution however the folder structure of the build output is different. The reason the output is not in the same structure as VS is because the TFS build template overrides the $(OutDir) property to point to the "binaries" folder on the build agent.

In TFS 2012 / .net 4.5 you can control this behaviour by passing an msbuild argument in your build definition /p:GenerateProjectSpecificOutputFolder=true

See this blog for more info

2
votes

This happens because MSBuild and TFSBuild are two different products - on your local machine MSBuild is used to build your projects.

One method I have used to get round this issue is to be a bit more verbose and use a combination of ProjectDir and ConfigurationName. Here is an actual example where I'm copying some config files:

robocopy "$(ProjectDir)bin\$(ConfigurationName)" "...target folder..." *.config

(Note that I've removed the target path, it wasn't essential to the example)

This works regardless of whether the assembly is targeted for AnyCPU or x86/64, due to Microsoft's convention of including a slash as part of the folder name.