View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010502CMakeCMakepublic2010-04-01 18:092010-10-26 16:30
ReporterConrad 
Assigned ToBrad King 
PriorityhighSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionCMake 2.8.3Fixed in VersionCMake 2.8.3 
Summary0010502: *.vcxproj files for Visual Studio 2010 RC should only be modified / get new timestamp if content changes
DescriptionSee also Note 0000002 at Issue# 0010481.

Writing the .vcxproj project files uses "SetCopyIfDifferent(true);", which is necessary but not sufficient. Some contents of the .vcxproj file are stored in cmVisualStudio10TargetGenerator.cxx as std::set< pointer >. Sets of pointers 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 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, we sort the items before iterating through them. There are a million ways to do this, but I chose putting them into std::map< std::string, pointer > and iterating over the map. (Another option would be

In cmVisualStudio10TargetGenerator::WriteGroups(), change:
  
  std::set<cmSourceGroup*> groupsUsed;
  std::vector<cmSourceFile*> clCompile;
  std::vector<cmSourceFile*> customBuild;
  std::vector<cmSourceFile*> none;
  std::vector<cmSourceFile*> headers;
  std::vector<cmSourceFile*> resource;
  
  for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
      s != classes.end(); s++)
    {
    cmSourceFile* sf = *s;
    std::string const& source = sf->GetFullPath();
    cmSourceGroup& sourceGroup =
      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
    groupsUsed.insert(&sourceGroup);
    const char* lang = sf->GetLanguage();
    bool header = (*s)->GetPropertyAsBool("HEADER_FILE_ONLY")
      || this->GlobalGenerator->IgnoreFile
      ((*s)->GetExtension().c_str());

to:

  // We are writing a Visual Studio .vcxproj.filters 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, cmSourceFile*> OrderedClassesMap;
  OrderedClassesMap orderedClasses;
  for( std::vector<cmSourceFile*>::const_iterator i = classes.begin();
       i != classes.end(); ++i)
    {
    orderedClasses[(*i)->GetFullPath()] = (*i);
    }

  typedef std::map< std::string, cmSourceGroup*> OrderedGroupsMap;
  OrderedGroupsMap groupsUsed;
  std::vector<cmSourceFile*> clCompile;
  std::vector<cmSourceFile*> customBuild;
  std::vector<cmSourceFile*> none;
  std::vector<cmSourceFile*> headers;
  std::vector<cmSourceFile*> resource;
  
  for( OrderedClassesMap::const_iterator s = orderedClasses.begin();
       s != orderedClasses.end(); s++)
    {
    cmSourceFile* sf = (*s).second;
    std::string const& source = sf->GetFullPath();
    cmSourceGroup& sourceGroup =
      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
    groupsUsed[sourceGroup.GetName()] = (&sourceGroup);
    const char* lang = sf->GetLanguage();
    bool header = sf->GetPropertyAsBool("HEADER_FILE_ONLY")
      || this->GlobalGenerator->IgnoreFile
      (sf->GetExtension().c_str());

Also further down in that function change:

  for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
      g != groupsUsed.end(); ++g)
    {
    cmSourceGroup* sg = *g;

to:

  for(OrderedGroupsMap::iterator g = groupsUsed.begin();
      g != groupsUsed.end(); ++g)
    {
    cmSourceGroup* sg = (*g).second;

Also #include <map> at the top of the file.

This code is also being submitted on a 5 1/4 floppy for incorporation into SCCS per today's instructions from Bill Hoffman.
TagsNo tags attached.
Attached Files

 Relationships
related to 0010481closedBill Hoffman *.vcxproj.filters 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
(0022434)
Brad King (manager)
2010-10-07 10:15

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=973df7c0 [^]

 Issue History
Date Modified Username Field Change
2010-04-01 18:09 Conrad New Issue
2010-05-14 18:21 David Cole Relationship added related to 0010481
2010-05-14 18:22 David Cole Relationship added related to 0010589
2010-07-13 09:28 Bill Hoffman Status new => assigned
2010-07-13 09:28 Bill Hoffman Assigned To => David Cole
2010-09-09 17:46 David Cole Priority normal => high
2010-10-07 09:53 Brad King Assigned To David Cole => Brad King
2010-10-07 10:15 Brad King Note Added: 0022434
2010-10-07 10:15 Brad King Status assigned => closed
2010-10-07 10:15 Brad King Resolution open => fixed
2010-10-26 16:30 David Cole Fixed in Version => CMake 2.8.3
2010-10-26 16:30 David Cole Target Version => CMake 2.8.3


Copyright © 2000 - 2018 MantisBT Team