I spent hours now but I simply don't get it:
Why is a lib sub directory not honoured by the VS "fast up-to-date check"? If a lib output dir for libraries is set, the solution is always rebuild - if changes have been made or not does not matter. If \lib sub dir is removed it works. Why?
Here is what I tested so far:
Refer to the next code snippet. That one works perfectly. If several dependent project are asked to build multiple times they actually build only once if no changes have been made. The Visual Studio FastUpToDateCheck kicks in.
But if you change the line
<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutputPath>
to
<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\lib\</OutputPath>
it constantly rebuilds. Any ideas why?
ComponentBuild.props located next to .sln file
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\$(MSBuildProjectName)\</IntermediateOutputPath>
<UseCommonOutputDirectory>False</UseCommonOutputDirectory>
<DisableFastUpToDateCheck>false</DisableFastUpToDateCheck>
</PropertyGroup>
<PropertyGroup Condition=" '$(OutputType)' == 'Library' ">
<!-- To distinguish by \lib\ does not work, a rebuild is triggered since the up-to-date check fails -->
<!-- <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\lib\</OutputPath> -->
<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutputPath>
<OutDir>$(OutputPath)</OutDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(OutputType)' == 'Exe' ">
<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutputPath>
<OutDir>$(OutputPath)</OutDir>
</PropertyGroup>
</Project>
The file is included in csproj files just before Import Microsoft.CSharp.targets
:
.csproj file:
<!-- position of include is important, OutputType of project must be defined already -->
<Import Project="$(SolutionDir)ComponentBuild.props" Condition="Exists('$(SolutionDir)ComponentBuild.props')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
The behaviour becomes more weird, the more I test. I created two simple library projects A and B. B depends on A. I added above mentioned import and the FastUpToDateCheck works. After adding lib path to the library outputtype, it works when nothing else is changed. But when lib B project is cleaned, every subsequent builds do rebuild project B.
When adding lib path to the exe outputtype as well. The FastUpToDateCheck works again.
Then I removed the lib path again from output type exe, but the FastUpToDateCheck surprisingly still works - always. Even when cleaning the build, changing a class or deleting all obj and bin folders.
BUT as soon as I removed the lib path from the lib outputtype as well, i.e. I set back all to the original state, it FAILS. It rebuilds every time. The first line of the diagnostic output is
Project 'ClassLibrary1' is not up to date. Missing output file 'c:\Users\hg348\Documents\Visual Studio 2015\Projects\BuildTest\bin\Debug\AnyCPU\lib\ClassLibrary1.dll'
It still looks into lib path even though it isn't set any more. I think there is some nasty caching involved.
Can someone please verify this?