1
votes

I have a solution with several C++ projects. For some of the projects I need some custom file copy, e.g. to copy some configuration files to the output directory or to copy the output files of one project to a specific folder after build.

In some cases I don't want or cannot add these files to the projects directly through the Visual Studio IDE. I created simple .targets files which I can reuse and add to the projects which need the file copying.

Here is a simple example .targets file for copying configuration files:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup>
 <BuildDependsOn>
  $(BuildDependsOn);
  CopyCustom
 </BuildDependsOn>
 </PropertyGroup>
 <ItemGroup>
 <CustomFiles Include="$(ProjectDir)Config\**\*.xml" />
 </ItemGroup>
 <PropertyGroup>
 <DestCustFolder>$(OutDir)Config\</DestCustFolder>
 </PropertyGroup> 
 <Target Name="CopyCustom"
 Inputs="@(CustomFiles )"
 Outputs="@(CustomFiles ->'$(DestCustFolder)%(RecursiveDir)%(FileName)%(Extension)')"> 
 <Message Text="Copy custom files..." />
 <Copy SourceFiles="@(CustomFiles )" DestinationFiles="@(CustomFiles->'$(DestCustFolder)%(RecursiveDir)%(FileName)%(Extension)')" SkipUnchangedFiles="true" />
 </Target>
</Project>

Through the "Build Customization" dialog in Visual Studio I add it to the project so it will be included like this at the end of the project file:

 <ImportGroup Label="ExtensionTargets">
<Import Project="..\Targets\CopyCustom.targets" />/
 </ImportGroup>

This should enable incremental build of my custom target. If I just edit one of my custom files (and none of the C++ files) and build it form the console with

msbuild foo1.vcxproj

it will actually detect the changes and does an incremental build for my custom target. If no changes are made the target is skipped.

If I do however build inside Visual Studio it will not detect changes to the custom files and only and gives me the message that the project is up to data:

========== Build: 0 succeeded, 0 failed, 5 up-to-date, 0 skipped ==========

I would have to additionally change one of the C++ files to make it check all targets again and to the incremental build.

I was expecting that Visual Studio just executes MSBuild which will then do the up-to-date check on the projects, so it should be the same result as running MSBuild from the console. I was trying to get more information by setting the verbosity level to diagnostic but I just get the same line. It seems to me that MSBuild is not even executed for the project but Visual Studio itself determines that the project is up-to-date.

So I was wondering how Visual Studio actually determines when it should execute MSBuild for a project.

I asked basically the same question before on the MSDN forum but couldn't get a clear answer.

2
It still implements the /Gm option, it still uses the .idb file. Enough evidence that dependency checking didn't fundamentally change in VS2010.Hans Passant
We disabled the /Gm option in our projects since its incompatible with the /MP option, so no .idb files are created.Hoschie0815
Also MSBuild 4.0 has the new File Tracker feature for incremental builds which generates .tlog files and the .idb files are no longer used. But all this should only apply to the incremental build of the C++ compilation target in MSBuild and not for the incremental build of the custom target.Hoschie0815
Are your custom files included in C++ project?Oleg Svechkarenko
Some custom files are included but some other files should not be included in the C++ projects.Hoschie0815

2 Answers

4
votes

See this suggestion on Microsoft Connect.

Basically you need to set DisableFastUpToDateCheck property to true to disable the fast-up-to-date check.

Just add to your vcxproj or your targets file:

<PropertyGroup>  
  <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
1
votes

I found an answer by looking into the book "Inside the Microsoft Build Engine, Second Edition".

Note: I also updated the same in my question in the MSDN forum but I will mainly duplicate the text here again for completeness.

On page 280 they actually saying that the IDE does a "fast up-to-date check" on the project-level. It only spawns a project build and does a more fine-grained check on the individual tasks if this rough project-level check fails.

When running MSBuild from the command line however there is always a fine-grained up-to-date check on the individual tools.

So the IDE only seems to do this fast check on the files which are added to the projects directly and set as one of the "Input File" types.

In my opinion this is not a good design. I would prefer that the IDE is only used to edit the MSBuild project files and then just invokes MSBuild to do the up-to-date check. This would make it much clearer.

I can understand that in a solution with a lot of projects it can make the up-to-date check much faster but there should be at least an option to disable the fast up-to-date check. I was checking the IDE if there is a way to disable this behavior but could not find anything.

The solution suggested here actually works and I am using it at the moment. But I added several custom targets for different kinds of custom files. If I add a new custom file I should never forget to set it to "Custom Build Tool" otherwise the incremental build for this file will not work.

I guess a solution would be to make a full build customization for my custom files and use specific file extensions for them so Visual Studio will automatically detect them when I add them to the project and sets the right Item Type.