So say I have SolutionA that has ProjectA that outputs:
A post build step on our CI server copies this build output to a specific LocationA ( a build artifact folder to be specific)
Then we have SolutionB, that has ProjectB, that has a reference to ProjectA in LocationA. The static checker picks ProjectA.Contracts.dll just fine. All good.
The build output from SolutionB is:
Note, ProjectA.Contracts.dll is not part of the build output. Post build step copies this output to LocationB.
Now, we have a third solution, SolutionC, that has ProjectC, that has explicit dependency on ProjectB and implicit dependency on ProjectA. Both of which are in LocationB.
The problem here is that static checker, when analyzing ProjectC, has no access to ProjectA.Contracts.dll and so has warnings.
What I think I would like is to have ProjectB's output look like:
bin\Release\CodeContracts\ProjectA.Contracts.dll <- include this in output
And correspondingly, I'd like ProjectC's output to look like:
Add an AfterTarget the Microsoft.CodeContracts.targets file (%ProgramFiles(x86)%\Microsoft\Contracts\MsBuild\v4.0 and \3.5) that will copy it's code contracts reference assemblies, if they exist, to the output directory of the project being compiled:
Copy reference's Contract Reference Assembles that are marked as "CopyLocal"
Condition="'@(ReferenceCopyLocalPaths)' != ''"
Condition="'$(UseCommonOutputDirectory)' != 'true' And Exists('%(RootDir)%(Directory)%(Filename)%(Extension)')"
<Output TaskParameter="CopiedFiles" ItemName="CodeContractsReferenceAssembliesCopiedFiles"/>
This will need to be done on your build server too.
We have been using this at my company for several months now without issues.
Original discussion. Thx to Mike Barnett for the suggestion.