summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2012-04-27 18:13:02 (GMT)
committerBrad King <brad.king@kitware.com>2012-04-27 18:14:36 (GMT)
commitd931ce9fe0c26cfddb766901cfd1ccbc9def71c7 (patch)
treee4644987b19c1ff0061dff199e2525268b81be91 /Source
parentb2e7c7aef0375d5d676632d8cc3a7c2d96d6a8fa (diff)
downloadCMake-d931ce9fe0c26cfddb766901cfd1ccbc9def71c7.zip
CMake-d931ce9fe0c26cfddb766901cfd1ccbc9def71c7.tar.gz
CMake-d931ce9fe0c26cfddb766901cfd1ccbc9def71c7.tar.bz2
VS10: Generate relative source paths when possible (#12570)
Since commit ed0075bd (Use relative paths for custom command inputs, 2011-06-22) CMake generates full paths to source files in VS 10 project files to avoid trouble with deep source/build tree paths. However, the VS 10 IDE will not populate the source file property dialog for a file referenced by full path. Instead use a relative path when possible. When not possible produce a detailed warning explaining the problem and suggesting use of shorter directory paths.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx48
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h14
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx19
3 files changed, 77 insertions, 4 deletions
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 28d738a..18a786d 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -13,6 +13,7 @@
#include "cmGlobalVisualStudio10Generator.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
#include "cmake.h"
@@ -51,6 +52,38 @@ cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
}
//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::Generate()
+{
+ this->LongestSource = LongestSourcePath();
+ this->cmGlobalVisualStudio8Generator::Generate();
+ if(this->LongestSource.Length > 0)
+ {
+ cmMakefile* mf = this->LongestSource.Target->GetMakefile();
+ cmOStringStream e;
+ e <<
+ "The binary and/or source directory paths may be too long to generate "
+ "Visual Studio 10 files for this project. "
+ "Consider choosing shorter directory names to build this project with "
+ "Visual Studio 10. "
+ "A more detailed explanation follows."
+ "\n"
+ "There is a bug in the VS 10 IDE that renders property dialog fields "
+ "blank for files referenced by full path in the project file. "
+ "However, CMake must reference at least one file by full path:\n"
+ " " << this->LongestSource.SourceFile->GetFullPath() << "\n"
+ "This is because some Visual Studio tools would append the relative "
+ "path to the end of the referencing directory path, as in:\n"
+ " " << mf->GetCurrentOutputDirectory() << "/"
+ << this->LongestSource.SourceRel << "\n"
+ "and then incorrectly complain that the file does not exist because "
+ "the path length is too long for some internal buffer or API. "
+ "To avoid this problem CMake must use a full path for this file "
+ "which then triggers the VS 10 property dialog bug.";
+ mf->IssueMessage(cmake::WARNING, e.str().c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudio10Generator
::GetDocumentation(cmDocumentationEntry& entry) const
{
@@ -230,3 +263,18 @@ cmGlobalVisualStudio10Generator
ruleFile += ".rule";
return ruleFile;
}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::PathTooLong(
+ cmTarget* target, cmSourceFile* sf, std::string const& sfRel)
+{
+ size_t len = (strlen(target->GetMakefile()->GetCurrentOutputDirectory()) +
+ 1 + sfRel.length());
+ if(len > this->LongestSource.Length)
+ {
+ this->LongestSource.Length = len;
+ this->LongestSource.Target = target;
+ this->LongestSource.SourceFile = sf;
+ this->LongestSource.SourceRel = sfRel;
+ }
+}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index e2cc14e..4236563 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -46,6 +46,8 @@ public:
///! create the correct local generator
virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual void Generate();
+
/**
* Try to determine system infomation such as shared library
* extension, pthreads, byte order etc.
@@ -79,10 +81,22 @@ public:
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
+ void PathTooLong(cmTarget* target, cmSourceFile* sf,
+ std::string const& sfRel);
protected:
virtual const char* GetIDEVersion() { return "10.0"; }
std::string PlatformToolset;
bool ExpressEdition;
+private:
+ struct LongestSourcePath
+ {
+ LongestSourcePath(): Length(0), Target(0), SourceFile(0) {}
+ size_t Length;
+ cmTarget* Target;
+ cmSourceFile* SourceFile;
+ std::string SourceRel;
+ };
+ LongestSourcePath LongestSource;
};
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index f8e4c30..9a97ab0 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -765,12 +765,23 @@ void cmVisualStudio10TargetGenerator::WriteSource(
// Normal path conversion resulted in a full path. VS 10 (but not 11)
// refuses to show the property page in the IDE for a source file with a
// full path (not starting in a '.' or '/' AFAICT). CMake <= 2.8.4 used a
- // relative path but to allow deeper build trees now CMake uses a full
- // path except for custom commands which work only as relative paths.
- if(sf->GetCustomCommand())
+ // relative path but to allow deeper build trees CMake 2.8.[5678] used a
+ // full path except for custom commands. Custom commands do not work
+ // without a relative path, but they do not seem to be involved in tools
+ // with the above behavior. For other sources we now use a relative path
+ // when the combined path will not be too long so property pages appear.
+ std::string sourceRel = this->ConvertPath(sf->GetFullPath(), true);
+ size_t const maxLen = 250;
+ if(sf->GetCustomCommand() ||
+ ((strlen(this->Makefile->GetCurrentOutputDirectory()) + 1 +
+ sourceRel.length()) <= maxLen))
{
forceRelative = true;
- sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative);
+ sourceFile = sourceRel;
+ }
+ else
+ {
+ this->GlobalGenerator->PathTooLong(this->Target, sf, sourceRel);
}
}
this->ConvertToWindowsSlash(sourceFile);