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.
This commit is contained in:
parent
b2e7c7aef0
commit
d931ce9fe0
|
@ -13,6 +13,7 @@
|
|||
#include "cmGlobalVisualStudio10Generator.h"
|
||||
#include "cmLocalVisualStudio10Generator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmake.h"
|
||||
|
||||
|
||||
|
@ -50,6 +51,38 @@ cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
|
|||
return lg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue