diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index d44359c20..06ac6485e 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -53,64 +53,76 @@ bool cmAddSubDirectoryCommand::InitialPass } } - // check for relative arguments - std::string binPath = binArg; - std::string srcPath = std::string(this->Makefile->GetCurrentDirectory()) + - "/" + srcArg; - // if the path does not exist then the arg was relative - if (!cmSystemTools::FileIsDirectory(srcPath.c_str())) + // Compute the full path to the specified source directory. + // Interpret a relative path with respect to the current source directory. + std::string srcPath; + if(cmSystemTools::FileIsFullPath(srcArg.c_str())) { srcPath = srcArg; - if (!cmSystemTools::FileIsDirectory(srcPath.c_str())) - { - std::string error = "Incorrect ADD_SUBDIRECTORY command. Directory: "; - error += srcArg + " does not exists."; - this->SetError(error.c_str()); - return false; - } } - - // at this point srcPath has the full path to the source directory - // now we need to compute the binPath if it was not provided - srcPath = cmSystemTools::CollapseFullPath(srcPath.c_str()); - - // if the argument was provided then use it - if (binArg.size()) - { - if (!cmSystemTools::FileIsFullPath(binPath.c_str())) - { - binPath = std::string(this->Makefile->GetCurrentOutputDirectory()) + - "/" + binArg.c_str(); - } - } - // otherwise compute the binPath from the srcPath else { - // we try to remove the CurrentDirectory from the srcPath and - // replace it with the CurrentOutputDirectory. This may not really work - // because the source dir they provided may not be "in" the source - // tree. This is an error if this happens. - // try replacing the home dir with the home output dir - binPath = srcPath; - if(!cmSystemTools::FindLastString(binPath.c_str(), - this->Makefile->GetHomeDirectory())) + srcPath = this->Makefile->GetCurrentDirectory(); + srcPath += "/"; + srcPath += srcArg; + } + if(!cmSystemTools::FileIsDirectory(srcPath.c_str())) + { + std::string error = "given source \""; + error += srcArg; + error += "\" which is not an existing directory."; + this->SetError(error.c_str()); + return false; + } + srcPath = cmSystemTools::CollapseFullPath(srcPath.c_str()); + + // Compute the full path to the binary directory. + std::string binPath; + if(binArg.empty()) + { + // No binary directory was specified. If the source directory is + // not a subdirectory of the current directory then it is an + // error. + if(!cmSystemTools::FindLastString(srcPath.c_str(), + this->Makefile->GetCurrentDirectory())) { - this->SetError("A full source directory was specified that is not " - "in the source tree but no binary directory was " - "specified. If you specify an out of tree source " - "directory then you must provide the binary " - "directory as well."); + cmOStringStream e; + e << "not given a binary directory but the given source directory " + << "\"" << srcPath << "\" is not a subdirectory of \"" + << this->Makefile->GetCurrentDirectory() << "\". " + << "When specifying an out-of-tree source a binary directory " + << "must be explicitly specified."; + this->SetError(e.str().c_str()); return false; } + + // Remove the CurrentDirectory from the srcPath and replace it + // with the CurrentOutputDirectory. + binPath = srcPath; cmSystemTools::ReplaceString(binPath, - this->Makefile->GetHomeDirectory(), - this->Makefile->GetHomeOutputDirectory()); + this->Makefile->GetCurrentDirectory(), + this->Makefile->GetCurrentOutputDirectory()); } - - // now we have all the arguments + else + { + // Use the binary directory specified. + // Interpret a relative path with respect to the current binary directory. + if(cmSystemTools::FileIsFullPath(binArg.c_str())) + { + binPath = binArg; + } + else + { + binPath = this->Makefile->GetCurrentOutputDirectory(); + binPath += "/"; + binPath += binArg; + } + } + binPath = cmSystemTools::CollapseFullPath(binPath.c_str()); + + // Add the subdirectory using the computed full paths. this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(), - intoplevel, false, true); + intoplevel, false, true); return true; } -