ENH: Add an invocation that maintains symbolic paths to the source and binary trees, mainly for systems with automounted network drives.

ENH: CollapseFullPath() no longer adds a trailing "/" to directory paths.
This commit is contained in:
Amitha Perera 2002-01-06 14:59:16 -05:00
parent 0e7e1c110c
commit 2fa6a0eb44
4 changed files with 121 additions and 47 deletions

View File

@ -94,6 +94,7 @@ inline int Chdir(const char* dir)
bool cmSystemTools::s_DisableRunCommandOutput = false; bool cmSystemTools::s_DisableRunCommandOutput = false;
bool cmSystemTools::s_ErrorOccured = false; bool cmSystemTools::s_ErrorOccured = false;
bool cmSystemTools::s_DisableMessages = false; bool cmSystemTools::s_DisableMessages = false;
cmSystemTools::PathMap cmSystemTools::s_PathMap;
void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, bool&); void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, bool&);
@ -1176,6 +1177,7 @@ std::string cmSystemTools::GetCurrentWorkingDirectory()
{ {
char buf[2048]; char buf[2048];
std::string path = Getcwd(buf, 2048); std::string path = Getcwd(buf, 2048);
ApplyPathTranslation( path );
return path; return path;
} }
@ -1237,6 +1239,7 @@ void cmSystemTools::SplitProgramPath(const char* in_name,
std::string cmSystemTools::CollapseFullPath(const char* in_name) std::string cmSystemTools::CollapseFullPath(const char* in_name)
{ {
std::string dir, file; std::string dir, file;
std::string return_value;
cmSystemTools::SplitProgramPath(in_name, dir, file); cmSystemTools::SplitProgramPath(in_name, dir, file);
#ifdef _WIN32 #ifdef _WIN32
// Ultra-hack warning: // Ultra-hack warning:
@ -1248,8 +1251,7 @@ std::string cmSystemTools::CollapseFullPath(const char* in_name)
Chdir(cwd.c_str()); Chdir(cwd.c_str());
cmSystemTools::ConvertToUnixSlashes(newDir); cmSystemTools::ConvertToUnixSlashes(newDir);
std::string newPath = newDir+"/"+file; return_value = newDir;
return newPath;
#else #else
# ifdef MAXPATHLEN # ifdef MAXPATHLEN
char resolved_name[MAXPATHLEN]; char resolved_name[MAXPATHLEN];
@ -1269,8 +1271,13 @@ std::string cmSystemTools::CollapseFullPath(const char* in_name)
{ {
dir = cmSystemTools::GetCurrentWorkingDirectory(); dir = cmSystemTools::GetCurrentWorkingDirectory();
} }
return dir + "/" + file; return_value = dir;
#endif #endif
if(file != "")
return_value += "/" + file;
ApplyPathTranslation( return_value );
return return_value;
} }
/** /**
@ -1424,3 +1431,24 @@ void cmSystemTools::GlobDirs(const char *fullPath,
} }
} }
} }
void cmSystemTools::AddPathTranslation( const std::string& from, const std::string& to )
{
s_PathMap[from] = to;
}
void cmSystemTools::ApplyPathTranslation( std::string& path )
{
PathMap::iterator i;
// For each key in the map, see if path starts with it. If so, perform the substitution.
for( i = s_PathMap.begin(); i != s_PathMap.end(); ++i )
{
if( path.substr( 0, i->first.length() ) == i->first )
{
path.replace( 0, i->first.length(), i->second );
return;
}
}
}

View File

@ -254,6 +254,16 @@ public:
std::string& file); std::string& file);
static std::string CollapseFullPath(const char*); static std::string CollapseFullPath(const char*);
/**
* all file path prefixes matching \arg from will be replaced by
* \arg to. Affects the return value of CollapseFullPath and
* GetCurrentWorkingDirectory.
*/
static void AddPathTranslation( const std::string& from, const std::string& to );
///! Apply the current path translations to \arg path.
static void ApplyPathTranslation( std::string& path );
///! return path of a full filename (no trailing slashes). ///! return path of a full filename (no trailing slashes).
static std::string GetFilenamePath(const std::string&); static std::string GetFilenamePath(const std::string&);
@ -295,6 +305,9 @@ private:
static bool s_DisableMessages; static bool s_DisableMessages;
static bool s_DisableRunCommandOutput; static bool s_DisableRunCommandOutput;
static ErrorCallback s_ErrorCallback; static ErrorCallback s_ErrorCallback;
typedef std::map<cmStdString, cmStdString> PathMap;
static PathMap s_PathMap;
}; };

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmake::cmake() cmake::cmake()
{ {
m_Verbose = false; m_Verbose = false;
m_UsePathTranslation = false;
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
cmMakefileGenerator::RegisterGenerator(new cmMSProjectGenerator); cmMakefileGenerator::RegisterGenerator(new cmMSProjectGenerator);
cmMakefileGenerator::RegisterGenerator(new cmNMakeMakefileGenerator); cmMakefileGenerator::RegisterGenerator(new cmNMakeMakefileGenerator);
@ -67,8 +68,9 @@ void cmake::Usage(const char* program)
std::cerr << "cmake version " << cmMakefile::GetMajorVersion() std::cerr << "cmake version " << cmMakefile::GetMajorVersion()
<< "." << cmMakefile::GetMinorVersion() << " - " << "." << cmMakefile::GetMinorVersion() << " - "
<< cmMakefile::GetReleaseVersion() << "\n"; << cmMakefile::GetReleaseVersion() << "\n";
std::cerr << "Usage: " << program << " [srcdir] [options]\n" std::cerr << "Usage: " << program << " [srcdir] [outdir] [options]\n"
<< "Where cmake is run from the directory where you want the object files written. If srcdir is not specified, the current directory is used for both source and object files.\n"; << "Where cmake is run from the directory where you want the object files written. If srcdir is not specified, the current directory is used for both source and object files.\n";
std::cerr << "If outdir is specified, pathname translation is enabled, and srcdir and outdir are used as given to access the roots of source and output directories.\n";
std::cerr << "Options are:\n"; std::cerr << "Options are:\n";
std::cerr << "\n-i (puts cmake in wizard mode, not available for ccmake)\n"; std::cerr << "\n-i (puts cmake in wizard mode, not available for ccmake)\n";
std::cerr << "\n-DVAR:TYPE=VALUE (create a cache file entry)\n"; std::cerr << "\n-DVAR:TYPE=VALUE (create a cache file entry)\n";
@ -128,29 +130,9 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
{ {
m_Local = false; m_Local = false;
bool directoriesSet = false; bool directoriesSet = false;
// watch for cmake and cmake srcdir invocations
if (args.size() <= 2) std::string srcdir;
{ std::string outdir;
directoriesSet = true;
builder.SetHomeOutputDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
builder.SetStartOutputDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
if (args.size() == 2)
{
builder.SetHomeDirectory
(cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
builder.SetStartDirectory
(cmSystemTools::CollapseFullPath(args[1].c_str()).c_str());
}
else
{
builder.SetHomeDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
builder.SetStartDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
}
}
for(unsigned int i=1; i < args.size(); ++i) for(unsigned int i=1; i < args.size(); ++i)
{ {
@ -159,6 +141,12 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
{ {
directoriesSet = true; directoriesSet = true;
std::string path = arg.substr(2); std::string path = arg.substr(2);
if( cmSystemTools::CollapseFullPath(path.c_str()) != path &&
path.size() > 0 && path[0] != '.' )
{
cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(path.c_str()), path );
m_UsePathTranslation = true;
}
builder.SetHomeDirectory(path.c_str()); builder.SetHomeDirectory(path.c_str());
} }
else if(arg.find("-S",0) == 0) else if(arg.find("-S",0) == 0)
@ -178,6 +166,12 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
{ {
directoriesSet = true; directoriesSet = true;
std::string path = arg.substr(2); std::string path = arg.substr(2);
if( cmSystemTools::CollapseFullPath(path.c_str()) != path &&
path.size() > 0 && path[0] != '.' )
{
cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(path.c_str()), path );
m_UsePathTranslation = true;
}
builder.SetHomeOutputDirectory(path.c_str()); builder.SetHomeOutputDirectory(path.c_str());
} }
else if(arg.find("-V",0) == 0) else if(arg.find("-V",0) == 0)
@ -207,31 +201,66 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
builder.SetMakefileGenerator(gen); builder.SetMakefileGenerator(gen);
} }
} }
// no option assume it is the path to the source // no option assume it is the path to the source or to the output
else else
{ {
directoriesSet = true; if( srcdir.size() == 0 )
builder.SetHomeOutputDirectory {
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); srcdir = arg;
builder.SetStartOutputDirectory }
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); else if( outdir.size() == 0 )
builder.SetHomeDirectory {
(cmSystemTools::CollapseFullPath(arg.c_str()).c_str()); // Make sure the symbolic output directory specified matches
builder.SetStartDirectory // the current directory, and that the symbolic path is
(cmSystemTools::CollapseFullPath(arg.c_str()).c_str()); // absolute. Even if not, set the outdir variable so that
// further attempts to set the output directory (with
// another command line argument) fails.
if( cmSystemTools::CollapseFullPath( arg.c_str() ) == cmSystemTools::GetCurrentWorkingDirectory() )
{
outdir = arg;
if( srcdir.size() > 0 && srcdir[0] != '.' && outdir.size() > 0 && outdir[0] != '.' )
{
cmSystemTools::AddPathTranslation( cmSystemTools::GetCurrentWorkingDirectory(), outdir );
cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(srcdir.c_str()), srcdir );
m_UsePathTranslation = true;
}
else
{
std::cerr << "Symbolic paths must be absolute for path translation. One of \"" << srcdir
<< "\" or \"" << outdir << "\" is not.\n"
<< "Not performing path name translation." << std::endl;
outdir = cmSystemTools::GetCurrentWorkingDirectory();
} }
} }
else
{
std::cerr << "The current working directory (" << cmSystemTools::GetCurrentWorkingDirectory() << ")\n"
<< "does not match the binary directory (" << (cmSystemTools::CollapseFullPath(arg.c_str())) << ")\n"
<< "[ given as " << arg << " ].\n"
<< "Not performing path name translation." << std::endl;
outdir = cmSystemTools::GetCurrentWorkingDirectory();
}
}
else
{
std::cerr << "Ignoring parameter " << arg << std::endl;
}
}
}
if(!directoriesSet) if(!directoriesSet)
{ {
builder.SetHomeOutputDirectory if( srcdir.size() == 0 ) srcdir = cmSystemTools::GetCurrentWorkingDirectory();
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
builder.SetStartOutputDirectory outdir = cmSystemTools::GetCurrentWorkingDirectory();
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); srcdir = cmSystemTools::CollapseFullPath( srcdir.c_str() );
builder.SetHomeDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); builder.SetHomeOutputDirectory( outdir.c_str() );
builder.SetStartDirectory builder.SetStartOutputDirectory( outdir.c_str() );
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); builder.SetHomeDirectory( srcdir.c_str() );
builder.SetStartDirectory( srcdir.c_str() );
} }
if (!m_Local) if (!m_Local)
{ {
builder.SetStartDirectory(builder.GetHomeDirectory()); builder.SetStartDirectory(builder.GetHomeDirectory());
@ -242,9 +271,12 @@ void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
// at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
void cmake::AddCMakePaths(const std::vector<std::string>& args) void cmake::AddCMakePaths(const std::vector<std::string>& args)
{ {
// Find our own executable. // Find our own executable. If path translations are enabled and the
// user supplies the full path to cmake, use it as the canonical
// name (i.e. don't translate to a local disk path).
std::string cMakeSelf = args[0]; std::string cMakeSelf = args[0];
cmSystemTools::ConvertToUnixSlashes(cMakeSelf); cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
if(!(m_UsePathTranslation && cmSystemTools::FileExists(cMakeSelf.c_str()) && cMakeSelf[0]!='.'))
cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str()); cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
if(!cmSystemTools::FileExists(cMakeSelf.c_str())) if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
{ {

View File

@ -83,5 +83,6 @@ class cmake
private: private:
bool m_Verbose; bool m_Verbose;
bool m_Local; bool m_Local;
bool m_UsePathTranslation;
}; };