I am overriding the Build target like this in my file OverrideBuild.targets:
<Target Name="OriginalBuild" DependsOnTargets="$(BuildDependsOn)"> <Message Text="Finished running target OriginalBuild" Importance="High" /> </Target> <Target Name="Build" > <CheckArtifacts ProjectGuid = "$(ProjectGuid)" SolutionPath = "$(SolutionPath)" > <Output PropertyName = "ArtifactsHaveChanged" TaskParameter = "Result" /> </CheckArtifacts> <Message Text="ArtifactsHaveChanged = $(ArtifactsHaveChanged)" Importance="high" /> <!-- if the artifacts.props file has not just been updated then we can run the original build target --> <Message Condition="'$(ArtifactsHaveChanged)' == 'false'" Text="Running target OriginalBuild" Importance="High" /> <CallTarget Condition="'$(ArtifactsHaveChanged)' == 'false'" Targets="OriginalBuild" /> <!-- Otherwise we need to run a new msbuild to avoid using an out-of-date cached version of the artifacts.props file. To force the msbuild process not to use the cached values from this process we must pass at least one property. --> <Message Condition="'$(ArtifactsHaveChanged)' == 'true'" Text="Running target OriginalBuild in nested msbuild" Importance="High" /> <MSBuild Condition="'$(ArtifactsHaveChanged)' == 'true'" Targets="OriginalBuild" Projects="$(MSBuildProjectFullPath)" Properties="InNestedMsbuild=true" /> <!-- Visual Studio doesn't pick up on the modified artifacts.props file unless we force it to reload the solution --> <Touch Condition="'$(ArtifactsHaveChanged)' == 'true' and '$(BuildingInsideVisualStudio)' == 'true'" Files = "$(SolutionPath)" /> <Message Text="Finished running build target override" Importance="High" /> </Target> and each of my .vcxproj or .csproj files includes this file at the end:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="..\..\OverrideBuild.targets" /> </Project> This works as I want it to for the C++ projects but fails with the C# projects. When building a C# project via msbuild it fails because the command line to the C# compiler is missing reference arguments for local assemblies. For example, a C# file that has a line like this at the top of the file:
using My.Utils.Common; fails with the following error message:
error CS0234: The type or namespace name 'Common' does not exist in the namespace 'My.Utils' (are you missing an assembly reference?) And looking at the compiler command used it is missing this line:
/reference:C:\Code\scratch\Build\My.Utils.Common\Bin\Release\My.Utils.Common.dll That missing line is present when I comment out my override of the Build target. And weirdly enough it will build fine from within Visual Studio even with my Build override in place. It only fails when building using msbuild from the command line and only for C# projects.
I thought that the way I had overriden the Build target would be completely transparent but apparently it isn't. Can anybody shed some light on what is going wrong ?
The type or namespace name 'Utils' could not be found.