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 "cmGlobalVisualStudio10Generator.h"
|
||||||
#include "cmLocalVisualStudio10Generator.h"
|
#include "cmLocalVisualStudio10Generator.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmSourceFile.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,6 +51,38 @@ cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
|
||||||
return lg;
|
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
|
void cmGlobalVisualStudio10Generator
|
||||||
::GetDocumentation(cmDocumentationEntry& entry) const
|
::GetDocumentation(cmDocumentationEntry& entry) const
|
||||||
|
@ -230,3 +263,18 @@ cmGlobalVisualStudio10Generator
|
||||||
ruleFile += ".rule";
|
ruleFile += ".rule";
|
||||||
return ruleFile;
|
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
|
///! create the correct local generator
|
||||||
virtual cmLocalGenerator *CreateLocalGenerator();
|
virtual cmLocalGenerator *CreateLocalGenerator();
|
||||||
|
|
||||||
|
virtual void Generate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to determine system infomation such as shared library
|
* Try to determine system infomation such as shared library
|
||||||
* extension, pthreads, byte order etc.
|
* extension, pthreads, byte order etc.
|
||||||
|
@ -79,10 +81,22 @@ public:
|
||||||
/** Generate an <output>.rule file path for a given command output. */
|
/** Generate an <output>.rule file path for a given command output. */
|
||||||
virtual std::string GenerateRuleFile(std::string const& output) const;
|
virtual std::string GenerateRuleFile(std::string const& output) const;
|
||||||
|
|
||||||
|
void PathTooLong(cmTarget* target, cmSourceFile* sf,
|
||||||
|
std::string const& sfRel);
|
||||||
protected:
|
protected:
|
||||||
virtual const char* GetIDEVersion() { return "10.0"; }
|
virtual const char* GetIDEVersion() { return "10.0"; }
|
||||||
|
|
||||||
std::string PlatformToolset;
|
std::string PlatformToolset;
|
||||||
bool ExpressEdition;
|
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
|
#endif
|
||||||
|
|
|
@ -765,12 +765,23 @@ void cmVisualStudio10TargetGenerator::WriteSource(
|
||||||
// Normal path conversion resulted in a full path. VS 10 (but not 11)
|
// 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
|
// 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
|
// 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
|
// relative path but to allow deeper build trees CMake 2.8.[5678] used a
|
||||||
// path except for custom commands which work only as relative paths.
|
// full path except for custom commands. Custom commands do not work
|
||||||
if(sf->GetCustomCommand())
|
// 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;
|
forceRelative = true;
|
||||||
sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative);
|
sourceFile = sourceRel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->GlobalGenerator->PathTooLong(this->Target, sf, sourceRel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->ConvertToWindowsSlash(sourceFile);
|
this->ConvertToWindowsSlash(sourceFile);
|
||||||
|
|
Loading…
Reference in New Issue