View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010481CMakeCMakepublic2010-03-29 14:182016-06-10 14:31
ReporterConrad 
Assigned ToBill Hoffman 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionFixed in Version 
Summary0010481: *.vcxproj.filters files for Visual Studio 2010 RC should only be modified / get new timestamp if content changes
DescriptionCMake seems to generate <project>.vcxproj.filters files in addition to the regular <project>.vcxproj project files. From their contents these appear to be rules about how to organize files within folders in a project, and may result from using SOURCE_GROUPS in our CMake files.

Every time CMake reruns to regenerate the .sln/.vcxproj files, these files get regenerated, and Visual Studio asks whether or not to reload them - this is problematic when you have 100+ projects in your solution and have to respond to each dialog.

CMake already does an excellent job of only modifying the .vcproj/.vcxproj files when their content actually changes. Suggest doing the same thing for the .vcxproj.filters files.
TagsNo tags attached.
Attached Filespatch file icon 0001-fix-permanent-vs10-project-filters-modification.patch [^] (3,157 bytes) 2014-11-07 14:02 [Show Content]

 Relationships
related to 0010502closedBrad King *.vcxproj files for Visual Studio 2010 RC should only be modified / get new timestamp if content changes 
related to 0010589closed Spurious re-running of CMake in VS2010 Qt-based projects 

  Notes
(0020031)
Conrad (reporter)
2010-03-30 02:37

I just checked out the latest CMake code and managed to fix this.

All the right pieces are there, so I just had to add one line to cmVisualStudio10TargetGenerator.cxx. Right after the line:
  this->BuildFileStream = & fout;
add:
  this->BuildFileStream->SetCopyIfDifferent(true);

I'm new to git and probably don't have commit authority.
(0020053)
Conrad (reporter)
2010-04-01 17:54

The above "SetCopyIfDifferent(true);" code was necessary but not sufficient. Contents of the .vcxproj.filters file are stored in cmVisualStudio10TargetGenerator.cxx as a cmGlobalGenerator::TargetDependSet, which is an std::set< T* >. Sets by default are ordered by pointer value, which is essentially random and at the mercy of malloc(). Therefore often when CMake is rerun, the .vcxproj.filters file would show as changed, thus constantly prompting the user to reload the files, even though only the ordering of items in the list had changed.

To fix this, in cmVisualStudio10TargetGenerator::WriteProjectReferences(), change:

  this->WriteString("<ItemGroup>\n", 1);
  for( cmGlobalGenerator::TargetDependSet::const_iterator i = depends.begin();
       i != depends.end(); ++i)
    {

to:


  // We are writing a Visual Studio .vcxproj file which may be
  // currently open in Visual Studio. Visual Studio will notice if the file
  // changes and prompt the user to reload it, which is very annoying when
  // nothing has actually changed. We already use SetCopyIfDifferent(true)
  // on the output stream, but if the order in which items are listed in the
  // file changes, the file will be considered different and be reloaded.
  //
  // std::set< T* > by default orders by pointer value, which is at the
  // mercy of malloc() and essentially random. Instead sort by name, so
  // that ordering is consistent from one CMake run to the next.
  typedef std::map< std::string, cmTarget* > SortedTargetDependMap;
  SortedTargetDependMap orderedDepends;
  for( cmGlobalGenerator::TargetDependSet::const_iterator i = depends.begin();
       i != depends.end(); ++i)
    {
      orderedDepends[(*i)->GetName()] = (*i);
    }

  this->WriteString("<ItemGroup>\n", 1);
  for( SortedTargetDependMap::const_iterator i = orderedDepends.begin();
       i != orderedDepends.end(); ++i)
    {
    cmTarget* dt = (*i).second;


Also #include <map> at the top of the file...
(0020066)
Conrad (reporter)
2010-04-02 16:10

I just stumbled upon the protected "class OrderedTargetDependSet" in the "protected:" section of cmGlobalVisualStudioGenerator.h.

So a cleaner and simpler solution is:

1. Move "struct TargetCompare" and "class OrderedTargetDependSet" from the protected to the public section of cmGlobalVisualStudioGenerator.h.

2. Change the first few lines of cmVisualStudio10TargetGenerator::WriteProjectReferences() to:

  // Must sort dependencies so they show up in a consistent order every
  // time CMake is rerun. Otherwise users get prompted to reload the
  // *.vcxproj.filters files constantly.
  cmGlobalVisualStudioGenerator::OrderedTargetDependSet depends
    = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);

  this->WriteString("<ItemGroup>\n", 1);
  for( cmGlobalVisualStudioGenerator::OrderedTargetDependSet::const_iterator i = depends.begin();
       i != depends.end(); ++i)
    {
    cmTarget* dt = *i;

Obviously we also need the:
  this->BuildFileStream->SetCopyIfDifferent(true);
fix described in my first note.
(0020381)
Vladislav Vaintroub (reporter)
2010-04-23 15:47

Yep, this is painful. I do have 70+ projects and I did not even try to count how many "ok" buttons I need to push after "cmake ." (guess around 150, once reload dialog for filters, and another one for projects)
(0020746)
David Cole (manager)
2010-05-14 18:19

Bill, the code that I committed today may only be a partial fix... According to the other notes here, we may also have to order things differently...?

Since I'm on vacation next week, I'm assigning to you. If it can be dealt with the week after or later, then feel free to assign back to me.

Thanks,
Dave
(0020747)
David Cole (manager)
2010-05-14 18:20

Partially? fixed by this commit to git master of CMake:

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7220df021be73cba540c72fcac86e59b84797375 [^]
(0021346)
Conrad (reporter)
2010-07-10 21:13

I just wanted to point out that the 2010-05-14 fix is insufficient, as I noted above, because the entries in the generated files are not written in a consistent order, so BuildFileStream correctly decides that the files are different from their predecessors.

I think the best fix is the one I pointed out in my 2010-04-02 note. It uses the existing tool for ordering entries within a project (class OrderedTargetDependSet) and really only requires a few lines of extra code to prevent the *.vcxproj.filters files from being constantly regenerated.
(0037162)
Nikolay Shelukhin (reporter)
2014-11-07 14:08

The problem seems to be not fixed completely.
Add a patch (0001-fix-permanent-vs10-project-filters-modification.patch) that fixes random order of 'Filter' entries.

<Filter Include="...">
  <UniqueIdentifier>...</UniqueIdentifier>
</Filter>
(0041675)
Kitware Robot (administrator)
2016-06-10 14:27

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2010-03-29 14:18 Conrad New Issue
2010-03-30 02:37 Conrad Note Added: 0020031
2010-04-01 17:54 Conrad Note Added: 0020053
2010-04-02 16:10 Conrad Note Added: 0020066
2010-04-23 15:47 Vladislav Vaintroub Note Added: 0020381
2010-05-14 18:17 David Cole Status new => assigned
2010-05-14 18:17 David Cole Assigned To => Bill Hoffman
2010-05-14 18:19 David Cole Note Added: 0020746
2010-05-14 18:20 David Cole Note Added: 0020747
2010-05-14 18:21 David Cole Relationship added related to 0010502
2010-05-14 18:21 David Cole Relationship added related to 0010589
2010-07-10 21:13 Conrad Note Added: 0021346
2014-11-07 14:02 Nikolay Shelukhin File Added: 0001-fix-permanent-vs10-project-filters-modification.patch
2014-11-07 14:08 Nikolay Shelukhin Note Added: 0037162
2016-06-10 14:27 Kitware Robot Note Added: 0041675
2016-06-10 14:27 Kitware Robot Status assigned => resolved
2016-06-10 14:27 Kitware Robot Resolution open => moved
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team