diff options
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 574 |
1 files changed, 49 insertions, 525 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index eb6b871..6f98ee2 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -46,7 +46,7 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, cmState::Snapshot snapshot) - : StateSnapshot(snapshot) + : cmOutputConverter(snapshot), StateSnapshot(snapshot) { assert(snapshot.IsValid()); this->GlobalGenerator = gg; @@ -58,9 +58,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, this->Makefile = new cmMakefile(this); - this->LinkScriptShell = false; - this->UseRelativePaths = false; - this->Configured = false; this->EmitUniversalBinaryFlags = true; this->BackwardsCompatibility = 0; this->BackwardsCompatibilityFinal = false; @@ -71,79 +68,20 @@ cmLocalGenerator::~cmLocalGenerator() delete this->Makefile; } -bool cmLocalGenerator::IsRootMakefile() const +void cmLocalGenerator::IssueMessage(cmake::MessageType t, + std::string const& text) const { - return !this->StateSnapshot.GetParent().IsValid(); -} + cmListFileContext lfc; + lfc.FilePath = this->StateSnapshot.GetCurrentSourceDirectory(); + lfc.FilePath += "/CMakeLists.txt"; -//---------------------------------------------------------------------------- -class cmLocalGeneratorCurrent -{ - cmGlobalGenerator* GG; - cmLocalGenerator* LG; - cmState::Snapshot Snapshot; -public: - cmLocalGeneratorCurrent(cmLocalGenerator* lg) + if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile()) { - this->GG = lg->GetGlobalGenerator(); - this->LG = this->GG->GetCurrentLocalGenerator(); - this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); - this->GG->GetCMakeInstance()->SetCurrentSnapshot(lg->GetStateSnapshot()); - this->GG->SetCurrentLocalGenerator(lg); -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PushFileScope(); -#endif + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmLocalGenerator::HOME); } - ~cmLocalGeneratorCurrent() - { -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PopFileScope(); -#endif - this->GG->SetCurrentLocalGenerator(this->LG); - this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); - } -}; - -//---------------------------------------------------------------------------- -void cmLocalGenerator::Configure() -{ - // Manage the global generator's current local generator. - cmLocalGeneratorCurrent clg(this); - static_cast<void>(clg); - - // make sure the CMakeFiles dir is there - std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory(); - filesDir += cmake::GetCMakeFilesDirectory(); - cmSystemTools::MakeDirectory(filesDir.c_str()); - - std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory(); - currentStart += "/CMakeLists.txt"; - assert(cmSystemTools::FileExists(currentStart.c_str(), true)); - this->Makefile->ProcessBuildsystemFile(currentStart.c_str()); - - // at the end of the ReadListFile handle any old style subdirs - // first get all the subdirectories - std::vector<cmLocalGenerator *> subdirs = this->GetChildren(); - - // for each subdir recurse - std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - if (!(*sdi)->Configured) - { - this->Makefile->ConfigureSubDirectory(*sdi); - } - } - - this->Makefile->AddCMakeDependFilesFromUser(); - - // Check whether relative paths should be used for optionally - // relative paths. - this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS"); - - this->ComputeObjectMaxPath(); - - this->Configured = true; + lfc.Line = 0; + this->GlobalGenerator->GetCMakeInstance()->IssueMessage(t, text, lfc); } //---------------------------------------------------------------------------- @@ -171,7 +109,7 @@ void cmLocalGenerator::ComputeObjectMaxPath() w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax << ", which is less than the minimum of 128. " << "The value will be ignored."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } } else @@ -180,17 +118,12 @@ void cmLocalGenerator::ComputeObjectMaxPath() w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen << "\", which fails to parse as a positive integer. " << "The value will be ignored."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } } this->ObjectMaxPathViolations.clear(); } -void cmLocalGenerator::ConfigureFinalPass() -{ - this->Makefile->ConfigureFinalPass(); -} - void cmLocalGenerator::TraceDependencies() { std::vector<std::string> configs; @@ -522,7 +455,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, objectDir = this->Convert(objectDir,START_OUTPUT,SHELL); std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL); std::string sourceFile = - this->Convert(source.GetFullPath(),START_OUTPUT,SHELL,true); + this->ConvertToOutputFormat(source.GetFullPath(), SHELL); std::string varString = "CMAKE_"; varString += lang; varString += "_COMPILE_OBJECT"; @@ -1169,56 +1102,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target, //---------------------------------------------------------------------------- std::string -cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote, - std::string const& result, - OutputFormat format) -{ - // If this is a windows shell, the result has a space, and the path - // already exists, we can use a short-path to reference it without a - // space. - if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos && - cmSystemTools::FileExists(remote.c_str())) - { - std::string tmp; - if(cmSystemTools::GetShortPath(remote, tmp)) - { - return this->Convert(tmp, NONE, format, true); - } - } - - // Otherwise, leave it unchanged. - return result; -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote, - RelativeRoot local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - return this->ConvertToOutputForExistingCommon(remote, result, format); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote, - const std::string& local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - const char* remotePath = this->GetRelativeRootPath(remote); - return this->ConvertToOutputForExistingCommon(remotePath, result, format); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToIncludeReference(std::string const& path, OutputFormat format, bool forceFullPaths) @@ -1316,8 +1199,7 @@ std::string cmLocalGenerator::GetIncludeFlags( { includeFlags << fwSearchFlag; } - includeFlags << this->Convert(frameworkDir, START_OUTPUT, - shellFormat, true) + includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat) << " "; } continue; @@ -1446,7 +1328,7 @@ void cmLocalGenerator::AddCompileOptions( "higher \"" << it->first << "_STANDARD\" \"" << standard << "\". " "This is not permitted. The COMPILE_FEATURES may not both depend on " "and be depended on by the link implementation." << std::endl; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } } @@ -1459,7 +1341,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, const std::string& lang, const std::string& config, bool stripImplicitInclDirs - ) + ) const { // Need to decide whether to automatically include the source and // binary directories at the beginning of the include path. @@ -2170,7 +2052,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target, "dialect \"" << lang << standardProp << "\" " << (ext ? "(with compiler extensions)" : "") << ", but CMake " "does not know the compile flags to use to enable it."; - this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->IssueMessage(cmake::FATAL_ERROR, e.str()); } else { @@ -2214,7 +2096,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target, std::string e = "CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) + "'"; - this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, e); + this->IssueMessage(cmake::INTERNAL_ERROR, e); return; } @@ -2430,7 +2312,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, << flagsVar << " was removed.\n" << cmPolicies::GetPolicyWarning(cmPolicies::CMP0018); - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); // fall through to OLD behaviour } case cmPolicies::OLD: @@ -2644,6 +2526,33 @@ void cmLocalGenerator::AppendFeatureOptions( } //---------------------------------------------------------------------------- +const char* cmLocalGenerator::GetFeature(const std::string& feature, + const std::string& config) +{ + // TODO: Define accumulation policy for features (prepend, append, replace). + // Currently we always replace. + if(!config.empty()) + { + std::string featureConfig = feature; + featureConfig += "_"; + featureConfig += cmSystemTools::UpperCase(config); + if(const char* value = this->Makefile->GetProperty(featureConfig)) + { + return value; + } + } + if(const char* value = this->Makefile->GetProperty(feature)) + { + return value; + } + if(cmLocalGenerator* parent = this->GetParent()) + { + return parent->GetFeature(feature, config); + } + return 0; +} + +//---------------------------------------------------------------------------- std::string cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, const char* default_comment) @@ -2675,242 +2584,6 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, } //---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOptionallyRelativeOutputPath( - const std::string& remote) -{ - return this->Convert(remote, START_OUTPUT, SHELL, true); -} - -//---------------------------------------------------------------------------- -const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot) -{ - switch (relroot) - { - case HOME: return this->GetState()->GetSourceDirectory(); - case START: return this->StateSnapshot.GetCurrentSourceDirectory(); - case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory(); - case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory(); - default: break; - } - return 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(const std::string& source, - RelativeRoot relative, - OutputFormat output, - bool optional) -{ - // Convert the path to a relative path. - std::string result = source; - - if (!optional || this->UseRelativePaths) - { - switch (relative) - { - case HOME: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->GetState()->GetSourceDirectoryComponents(), result); - break; - case START: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result); - break; - case HOME_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->GetState()->GetBinaryDirectoryComponents(), result); - break; - case START_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result); - break; - case FULL: - result = cmSystemTools::CollapseFullPath(result); - break; - case NONE: - break; - } - } - return this->ConvertToOutputFormat(result, output); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source, - OutputFormat output) -{ - std::string result = source; - // Convert it to an output path. - if (output == MAKERULE) - { - result = cmSystemTools::ConvertToOutputPath(result.c_str()); - } - else if(output == SHELL || output == WATCOMQUOTE) - { - // For the MSYS shell convert drive letters to posix paths, so - // that c:/some/path becomes /c/some/path. This is needed to - // avoid problems with the shell path translation. - if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell) - { - if(result.size() > 2 && result[1] == ':') - { - result[1] = result[0]; - result[0] = '/'; - } - } - if(this->GetState()->UseWindowsShell()) - { - std::replace(result.begin(), result.end(), '/', '\\'); - } - result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); - } - else if(output == RESPONSE) - { - result = this->EscapeForShell(result, false, false, false); - } - return result; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(RelativeRoot remote, - const std::string& local, - OutputFormat output, - bool optional) -{ - const char* remotePath = this->GetRelativeRootPath(remote); - - // The relative root must have a path (i.e. not FULL or NONE) - assert(remotePath != 0); - - if(!local.empty() && (!optional || this->UseRelativePaths)) - { - std::vector<std::string> components; - cmSystemTools::SplitPath(local, components); - std::string result = this->ConvertToRelativePath(components, remotePath); - return this->ConvertToOutputFormat(result, output); - } - else - { - return this->ConvertToOutputFormat(remotePath, output); - } -} - -//---------------------------------------------------------------------------- -static bool cmLocalGeneratorNotAbove(const char* a, const char* b) -{ - return (cmSystemTools::ComparePath(a, b) || - cmSystemTools::IsSubDirectory(a, b)); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, - const std::string& in_remote, - bool force) -{ - // The path should never be quoted. - assert(in_remote[0] != '\"'); - - // The local path should never have a trailing slash. - assert(!local.empty() && !(local[local.size()-1] == "")); - - // If the path is already relative then just return the path. - if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) - { - return in_remote; - } - - if(!force) - { - // Skip conversion if the path and local are not both in the source - // or both in the binary tree. - std::string local_path = cmSystemTools::JoinPath(local); - if(!((cmLocalGeneratorNotAbove(local_path.c_str(), - this->StateSnapshot.GetRelativePathTopBinary()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->StateSnapshot.GetRelativePathTopBinary())) || - (cmLocalGeneratorNotAbove(local_path.c_str(), - this->StateSnapshot.GetRelativePathTopSource()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->StateSnapshot.GetRelativePathTopSource())))) - { - return in_remote; - } - } - - // Identify the longest shared path component between the remote - // path and the local path. - std::vector<std::string> remote; - cmSystemTools::SplitPath(in_remote, remote); - unsigned int common=0; - while(common < remote.size() && - common < local.size() && - cmSystemTools::ComparePath(remote[common], - local[common])) - { - ++common; - } - - // If no part of the path is in common then return the full path. - if(common == 0) - { - return in_remote; - } - - // If the entire path is in common then just return a ".". - if(common == remote.size() && - common == local.size()) - { - return "."; - } - - // If the entire path is in common except for a trailing slash then - // just return a "./". - if(common+1 == remote.size() && - remote[common].empty() && - common == local.size()) - { - return "./"; - } - - // Construct the relative path. - std::string relative; - - // First add enough ../ to get up to the level of the shared portion - // of the path. Leave off the trailing slash. Note that the last - // component of local will never be empty because local should never - // have a trailing slash. - for(unsigned int i=common; i < local.size(); ++i) - { - relative += ".."; - if(i < local.size()-1) - { - relative += "/"; - } - } - - // Now add the portion of the destination path that is not included - // in the shared portion of the path. Add a slash the first time - // only if there was already something in the path. If there was a - // trailing slash in the input then the last iteration of the loop - // will add a slash followed by an empty string which will preserve - // the trailing slash in the output. - - if(!relative.empty() && !remote.empty()) - { - relative += "/"; - } - relative += cmJoin(cmRange(remote).advance(common), "/"); - - // Finally return the path. - return relative; -} - -//---------------------------------------------------------------------------- class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator { public: @@ -3151,7 +2824,7 @@ cmLocalGenerator << " " << ssin << "\n" << "cannot be safely placed under this directory. " << "The build may not work correctly."; - this->Makefile->IssueMessage(cmake::WARNING, m.str()); + this->IssueMessage(cmake::WARNING, m.str()); } } #else @@ -3195,11 +2868,6 @@ bool cmLocalGenerator::IsNMake() const return this->GetState()->UseNMake(); } -void cmLocalGenerator::SetConfiguredCMP0014(bool configured) -{ - this->Configured = configured; -} - //---------------------------------------------------------------------------- std::string cmLocalGenerator @@ -3308,150 +2976,6 @@ cmLocalGenerator } //---------------------------------------------------------------------------- -static bool cmLocalGeneratorIsShellOperator(const std::string& str) -{ - static std::set<std::string> shellOperators; - if(shellOperators.empty()) - { - shellOperators.insert("<"); - shellOperators.insert(">"); - shellOperators.insert("<<"); - shellOperators.insert(">>"); - shellOperators.insert("|"); - shellOperators.insert("||"); - shellOperators.insert("&&"); - shellOperators.insert("&>"); - shellOperators.insert("1>"); - shellOperators.insert("2>"); - shellOperators.insert("2>&1"); - shellOperators.insert("1>&2"); - } - return shellOperators.count(str) > 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForShell(const std::string& str, - bool makeVars, - bool forEcho, - bool useWatcomQuote) -{ - // Do not escape shell operators. - if(cmLocalGeneratorIsShellOperator(str)) - { - return str; - } - - // Compute the flags for the target shell environment. - int flags = 0; - if(this->GetState()->UseWindowsVSIDE()) - { - flags |= cmsysSystem_Shell_Flag_VSIDE; - } - else if(!this->LinkScriptShell) - { - flags |= cmsysSystem_Shell_Flag_Make; - } - if(makeVars) - { - flags |= cmsysSystem_Shell_Flag_AllowMakeVariables; - } - if(forEcho) - { - flags |= cmsysSystem_Shell_Flag_EchoWindows; - } - if(useWatcomQuote) - { - flags |= cmsysSystem_Shell_Flag_WatcomQuote; - } - if(this->GetState()->UseWatcomWMake()) - { - flags |= cmsysSystem_Shell_Flag_WatcomWMake; - } - if(this->GetState()->UseMinGWMake()) - { - flags |= cmsysSystem_Shell_Flag_MinGWMake; - } - if(this->GetState()->UseNMake()) - { - flags |= cmsysSystem_Shell_Flag_NMake; - } - - // Compute the buffer size needed. - int size = (this->GetState()->UseWindowsShell() ? - cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) : - cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags)); - - // Compute the shell argument itself. - std::vector<char> arg(size); - if(this->GetState()->UseWindowsShell()) - { - cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags); - } - else - { - cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags); - } - return std::string(&arg[0]); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForCMake(const std::string& str) -{ - // Always double-quote the argument to take care of most escapes. - std::string result = "\""; - for(const char* c = str.c_str(); *c; ++c) - { - if(*c == '"') - { - // Escape the double quote to avoid ending the argument. - result += "\\\""; - } - else if(*c == '$') - { - // Escape the dollar to avoid expanding variables. - result += "\\$"; - } - else if(*c == '\\') - { - // Escape the backslash to avoid other escapes. - result += "\\\\"; - } - else - { - // Other characters will be parsed correctly. - result += *c; - } - } - result += "\""; - return result; -} - -//---------------------------------------------------------------------------- -cmLocalGenerator::FortranFormat -cmLocalGenerator::GetFortranFormat(const char* value) -{ - FortranFormat format = FortranFormatNone; - if(value && *value) - { - std::vector<std::string> fmt; - cmSystemTools::ExpandListArgument(value, fmt); - for(std::vector<std::string>::iterator fi = fmt.begin(); - fi != fmt.end(); ++fi) - { - if(*fi == "FIXED") - { - format = FortranFormatFixed; - } - if(*fi == "FREE") - { - format = FortranFormatFree; - } - } - } - return format; -} - -//---------------------------------------------------------------------------- std::string cmLocalGenerator::GetTargetDirectory(cmTarget const&) const { @@ -3481,7 +3005,7 @@ cmIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility() } } this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch); - this->BackwardsCompatibilityFinal = this->Configured; + this->BackwardsCompatibilityFinal = this->Makefile->IsConfigured(); } return this->BackwardsCompatibility; |