diff options
Diffstat (limited to 'Source/cmMakefile.cxx')
-rw-r--r-- | Source/cmMakefile.cxx | 843 |
1 files changed, 513 insertions, 330 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index ee6c1da..ae69b24 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -19,6 +19,7 @@ #include "cmLocalGenerator.h" #include "cmCommands.h" #include "cmState.h" +#include "cmOutputConverter.h" #include "cmFunctionBlocker.h" #include "cmListFileCache.h" #include "cmCommandArgumentParserHelper.h" @@ -105,7 +106,7 @@ public: ++it; if(it == this->VarStack.rend()) { - cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent(); + cmLocalGenerator* plg = mf->LocalGenerator->GetParent(); if(!plg) { return false; @@ -146,11 +147,11 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); - this->GeneratingBuildSystem = false; + this->Configured = false; this->SuppressWatches = false; // Setup the default include file regular expression (match everything). - this->IncludeFileRegularExpression = "^.*$"; + this->SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$"); // Setup the default include complaint regular expression (match nothing). this->ComplainFileRegularExpression = "^$"; // Source and header file extensions that we can handle @@ -213,8 +214,6 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); #endif - this->Properties.SetCMakeInstance(this->GetCMakeInstance()); - { const char* dir = this->GetCMakeInstance()->GetHomeDirectory(); this->AddDefinition("CMAKE_SOURCE_DIR", dir); @@ -249,11 +248,11 @@ void cmMakefile::IssueMessage(cmake::MessageType t, std::string const& text) const { // Collect context information. - if(!this->CallStack.empty()) + if(!this->ExecutionStatusStack.empty()) { if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR)) { - this->CallStack.back().Status->SetNestedError(true); + this->ExecutionStatusStack.back()->SetNestedError(true); } this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace()); } @@ -262,12 +261,12 @@ void cmMakefile::IssueMessage(cmake::MessageType t, cmListFileContext lfc; // We are not currently executing a command. Add whatever context // information we have. - lfc.FilePath = this->ListFileStack.back(); + lfc.FilePath = this->GetExecutionFilePath(); if(!this->GetCMakeInstance()->GetIsInTryCompile()) { - lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, - cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); } lfc.Line = 0; this->GetCMakeInstance()->IssueMessage(t, text, lfc); @@ -277,26 +276,36 @@ void cmMakefile::IssueMessage(cmake::MessageType t, //---------------------------------------------------------------------------- cmListFileBacktrace cmMakefile::GetBacktrace() const { - cmListFileBacktrace backtrace(this->GetLocalGenerator()); - for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin(); - i != this->CallStack.rend(); ++i) + cmListFileBacktrace backtrace; + if (!this->ContextStack.empty()) { - backtrace.Append(*i->Context); + backtrace = cmListFileBacktrace(this->StateSnapshot, + *this->ContextStack.back()); } return backtrace; } //---------------------------------------------------------------------------- +cmListFileBacktrace +cmMakefile::GetBacktrace(cmCommandContext const& cc) const +{ + cmState::Snapshot snp = this->StateSnapshot; + return cmListFileBacktrace(snp, cc); +} + +//---------------------------------------------------------------------------- cmListFileContext cmMakefile::GetExecutionContext() const { - return *this->CallStack.back().Context; + return cmListFileContext::FromCommandContext( + *this->ContextStack.back(), + this->StateSnapshot.GetExecutionListFile()); } //---------------------------------------------------------------------------- void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const { std::ostringstream msg; - msg << lff.FilePath << "(" << lff.Line << "): "; + msg << this->GetExecutionFilePath() << "(" << lff.Line << "): "; msg << lff.Name << "("; for(std::vector<cmListFileArgument>::const_iterator i = lff.Arguments.begin(); i != lff.Arguments.end(); ++i) @@ -397,12 +406,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, class cmMakefile::IncludeScope { public: - IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope); + IncludeScope(cmMakefile* mf, std::string const& filenametoread, + bool noPolicyScope); ~IncludeScope(); void Quiet() { this->ReportError = false; } private: cmMakefile* Makefile; - const char* File; bool NoPolicyScope; bool CheckCMP0011; bool ReportError; @@ -410,9 +419,10 @@ private: }; //---------------------------------------------------------------------------- -cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname, +cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, + std::string const& filenametoread, bool noPolicyScope): - Makefile(mf), File(fname), NoPolicyScope(noPolicyScope), + Makefile(mf), NoPolicyScope(noPolicyScope), CheckCMP0011(false), ReportError(true) { if(!this->NoPolicyScope) @@ -446,11 +456,24 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname, // The included file cannot pop our policy scope. this->Makefile->PushPolicyBarrier(); + this->Makefile->PushFunctionBlockerBarrier(); + + this->Makefile->StateSnapshot = + this->Makefile->GetState()->CreateCallStackSnapshot( + this->Makefile->StateSnapshot, + this->Makefile->ContextStack.back()->Name, + this->Makefile->ContextStack.back()->Line, + filenametoread); } //---------------------------------------------------------------------------- cmMakefile::IncludeScope::~IncludeScope() { + this->Makefile->StateSnapshot = + this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot); + assert(this->Makefile->StateSnapshot.IsValid()); + + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); // Enforce matching policy scopes inside the included file. this->Makefile->PopPolicyBarrier(this->ReportError); @@ -489,7 +512,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011() { std::ostringstream w; w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n" - << "The included script\n " << this->File << "\n" + << "The included script\n " + << this->Makefile->GetExecutionFilePath() << "\n" << "affects policy settings. " << "CMake is implying the NO_POLICY_SCOPE option for compatibility, " << "so the effects are applied to the including context."; @@ -501,7 +525,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011() { std::ostringstream e; e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n" - << "The included script\n " << this->File << "\n" + << "The included script\n " + << this->Makefile->GetExecutionFilePath() << "\n" << "affects policy settings, so it requires this policy to be set."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } @@ -515,38 +540,121 @@ void cmMakefile::IncludeScope::EnforceCMP0011() } } -bool cmMakefile::ProcessBuildsystemFile(const char* listfile) +class cmParseFileScope { - this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile); - std::string curSrc = this->GetCurrentSourceDirectory(); - return this->ReadListFile(listfile, true, - curSrc == this->GetHomeDirectory()); -} +public: + cmParseFileScope(cmMakefile* mf) + : Makefile(mf) + { + this->Makefile->ContextStack.push_back(&this->Context); + } + + ~cmParseFileScope() + { + this->Makefile->ContextStack.pop_back(); + } -bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope) +private: + cmMakefile* Makefile; + cmCommandContext Context; +}; + +bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope) { this->AddDefinition("CMAKE_PARENT_LIST_FILE", this->GetDefinition("CMAKE_CURRENT_LIST_FILE")); - bool result = this->ReadListFile(listfile, noPolicyScope, false); - this->ListFileStack.pop_back(); - return result; + std::string filenametoread = + cmSystemTools::CollapseFullPath(filename, + this->GetCurrentSourceDirectory()); + + IncludeScope incScope(this, filenametoread, noPolicyScope); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(filenametoread.c_str(), false, this)) + { + return false; + } + } + + this->ReadListFile(listFile, filenametoread); + if(cmSystemTools::GetFatalErrorOccured()) + { + incScope.Quiet(); + } + return true; } -bool cmMakefile::ReadListFile(const char* listfile) +class cmMakefile::ListFileScope { - bool result = this->ReadListFile(listfile, true, false); - this->ListFileStack.pop_back(); - return result; -} +public: + ListFileScope(cmMakefile* mf, std::string const& filenametoread) + : Makefile(mf), ReportError(true) + { + this->Makefile->PushPolicyBarrier(); + + long line = 0; + std::string name; + if (!this->Makefile->ContextStack.empty()) + { + line = this->Makefile->ContextStack.back()->Line; + name = this->Makefile->ContextStack.back()->Name; + } + this->Makefile->StateSnapshot = + this->Makefile->GetState()->CreateInlineListFileSnapshot( + this->Makefile->StateSnapshot, name, line, filenametoread); + assert(this->Makefile->StateSnapshot.IsValid()); + this->Makefile->PushFunctionBlockerBarrier(); + } + + ~ListFileScope() + { + this->Makefile->StateSnapshot = + this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot); + assert(this->Makefile->StateSnapshot.IsValid()); + + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); + this->Makefile->PopPolicyBarrier(this->ReportError); + } -bool cmMakefile::ReadListFile(const char* listfile, - bool noPolicyScope, - bool requireProjectCommand) + void Quiet() { this->ReportError = false; } +private: + cmMakefile* Makefile; + bool ReportError; +}; + +bool cmMakefile::ReadListFile(const char* filename) { std::string filenametoread = - cmSystemTools::CollapseFullPath(listfile, + cmSystemTools::CollapseFullPath(filename, this->GetCurrentSourceDirectory()); + ListFileScope scope(this, filenametoread); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(filenametoread.c_str(), false, this)) + { + return false; + } + } + + this->ReadListFile(listFile, filenametoread); + if(cmSystemTools::GetFatalErrorOccured()) + { + scope.Quiet(); + } + return true; +} + +void cmMakefile::ReadListFile(cmListFile const& listFile, + std::string const& filenametoread) +{ + // add this list file to the list of dependencies + this->ListFiles.push_back(filenametoread); + std::string currentParentFile = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE"); std::string currentFile @@ -560,55 +668,14 @@ bool cmMakefile::ReadListFile(const char* listfile, this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); - this->ListFileStack.push_back(filenametoread); - - bool res = this->ReadListFileInternal(filenametoread.c_str(), - noPolicyScope, requireProjectCommand); - - this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); - this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str()); - this->AddDefinition("CMAKE_CURRENT_LIST_DIR", - cmSystemTools::GetFilenamePath(currentFile).c_str()); - this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); - this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); - this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); - - if (res) - { - this->CheckForUnusedVariables(); - } - - return res; -} - -bool cmMakefile::ReadListFileInternal(const char* filenametoread, - bool noPolicyScope, - bool requireProjectCommand) -{ - cmListFile cacheFile; - if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) ) - { - return false; - } - // add this list file to the list of dependencies - this->ListFiles.push_back( filenametoread); - - // Enforce balanced blocks (if/endif, function/endfunction, etc.). - { - LexicalPushPop lexScope(this); - IncludeScope incScope(this, filenametoread, noPolicyScope); - // Run the parsed commands. - const size_t numberFunctions = cacheFile.Functions.size(); + const size_t numberFunctions = listFile.Functions.size(); for(size_t i =0; i < numberFunctions; ++i) { cmExecutionStatus status; - this->ExecuteCommand(cacheFile.Functions[i],status); + this->ExecuteCommand(listFile.Functions[i],status); if(cmSystemTools::GetFatalErrorOccured()) { - // Exit early due to error. - lexScope.Quiet(); - incScope.Quiet(); break; } if(status.GetReturnInvoked()) @@ -617,16 +684,15 @@ bool cmMakefile::ReadListFileInternal(const char* filenametoread, break; } } - } - - // If this is the directory-level CMakeLists.txt file then perform - // some extra checks. - if(this->ListFileStack.size() == 1) - { - this->EnforceDirectoryLevelRules(); - } + this->CheckForUnusedVariables(); - return true; + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); + this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str()); + this->AddDefinition("CMAKE_CURRENT_LIST_DIR", + cmSystemTools::GetFilenamePath(currentFile).c_str()); + this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); + this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); + this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); } //---------------------------------------------------------------------------- @@ -1451,35 +1517,8 @@ void cmMakefile::AddLinkLibrary(const std::string& lib) this->AddLinkLibrary(lib,cmTarget::GENERAL); } -void cmMakefile::AddLinkDirectory(const std::string& dir) -{ - // Don't add a link directory that is already present. Yes, this - // linear search results in n^2 behavior, but n won't be getting - // much bigger than 20. We cannot use a set because of order - // dependency of the link search path. - - if(dir.empty()) - { - return; - } - std::string newdir = dir; - // remove trailing slashes - if(*dir.rbegin() == '/') - { - newdir = dir.substr(0, dir.size()-1); - } - if(std::find(this->LinkDirectories.begin(), - this->LinkDirectories.end(), newdir) - == this->LinkDirectories.end()) - { - this->LinkDirectories.push_back(dir); - } -} - -void cmMakefile::InitializeFromParent() +void cmMakefile::InitializeFromParent(cmMakefile* parent) { - cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile(); - // Initialize definitions with the closure of the parent scope. this->Internal->InitializeDefinitions(parent); @@ -1540,23 +1579,188 @@ void cmMakefile::InitializeFromParent() this->LinkLibraries = parent->LinkLibraries; // link directories - this->LinkDirectories = parent->LinkDirectories; + this->SetProperty("LINK_DIRECTORIES", + parent->GetProperty("LINK_DIRECTORIES")); // the initial project name this->ProjectName = parent->ProjectName; // Copy include regular expressions. - this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression; this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression; // Imported targets. this->ImportedTargets = parent->ImportedTargets; } -void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) +void cmMakefile::PushFunctionScope(std::string const& fileName, + const cmPolicies::PolicyMap& pm) +{ + this->StateSnapshot = + this->GetState()->CreateFunctionCallSnapshot( + this->StateSnapshot, + this->ContextStack.back()->Name, this->ContextStack.back()->Line, + fileName); + assert(this->StateSnapshot.IsValid()); + + this->Internal->PushDefinitions(); + + this->PushLoopBlockBarrier(); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope(); +#endif + + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopFunctionScope(bool reportError) +{ + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot); + assert(this->StateSnapshot.IsValid()); + + this->PopFunctionBlockerBarrier(reportError); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope(); +#endif + + this->PopLoopBlockBarrier(); + + this->CheckForUnusedVariables(); + + this->Internal->PopDefinitions(); +} + +void cmMakefile::PushMacroScope(std::string const& fileName, + const cmPolicies::PolicyMap& pm) +{ + this->StateSnapshot = + this->GetState()->CreateMacroCallSnapshot( + this->StateSnapshot, + this->ContextStack.back()->Name, this->ContextStack.back()->Line, + fileName); + assert(this->StateSnapshot.IsValid()); + + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopMacroScope(bool reportError) +{ + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot); + assert(this->StateSnapshot.IsValid()); + + this->PopFunctionBlockerBarrier(reportError); +} + +bool cmMakefile::IsRootMakefile() const +{ + return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid(); +} + +class cmMakefile::BuildsystemFileScope +{ +public: + BuildsystemFileScope(cmMakefile* mf) + : Makefile(mf), ReportError(true) + { + std::string currentStart = + this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(); + currentStart += "/CMakeLists.txt"; + this->Makefile->StateSnapshot.SetListFile(currentStart); + this->Makefile->PushPolicyBarrier(); + this->Makefile->PushFunctionBlockerBarrier(); + + this->GG = mf->GetGlobalGenerator(); + this->CurrentMakefile = this->GG->GetCurrentMakefile(); + this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); + this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); + this->GG->SetCurrentMakefile(mf); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PushFileScope(); +#endif + } + + ~BuildsystemFileScope() + { + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); + this->Makefile->PopPolicyBarrier(this->ReportError); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PopFileScope(); +#endif + this->GG->SetCurrentMakefile(this->CurrentMakefile); + this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); + } + + void Quiet() { this->ReportError = false; } +private: + cmMakefile* Makefile; + cmGlobalGenerator* GG; + cmMakefile* CurrentMakefile; + cmState::Snapshot Snapshot; + bool ReportError; +}; + +//---------------------------------------------------------------------------- +void cmMakefile::Configure() +{ + BuildsystemFileScope scope(this); + + // make sure the CMakeFiles dir is there + std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary(); + filesDir += cmake::GetCMakeFilesDirectory(); + cmSystemTools::MakeDirectory(filesDir.c_str()); + + std::string currentStart = + this->StateSnapshot.GetDirectory().GetCurrentSource(); + currentStart += "/CMakeLists.txt"; + assert(cmSystemTools::FileExists(currentStart.c_str(), true)); + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str()); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), this)) + { + this->SetConfigured(); + return; + } + } + this->ReadListFile(listFile, currentStart); + if(cmSystemTools::GetFatalErrorOccured()) + { + scope.Quiet(); + } + + // at the end handle any old style subdirs + std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories; + + // for each subdir recurse + std::vector<cmMakefile*>::iterator sdi = subdirs.begin(); + for (; sdi != subdirs.end(); ++sdi) + { + this->ConfigureSubDirectory(*sdi); + } + + this->AddCMakeDependFilesFromUser(); + this->SetConfigured(); +} + +void cmMakefile::ConfigureSubDirectory(cmMakefile *mf) { - lg2->GetMakefile()->InitializeFromParent(); - std::string currentStart = lg2->GetMakefile()->GetCurrentSourceDirectory(); + mf->InitializeFromParent(this); + std::string currentStart = mf->GetCurrentSourceDirectory(); if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Entering "; @@ -1594,11 +1798,12 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) // NEW behavior prints the error. this->IssueMessage(cmake::FATAL_ERROR, e.str()); } - lg2->SetConfiguredCMP0014(true); + mf->SetConfigured(); return; } // finally configure the subdir - lg2->Configure(); + mf->Configure(); + if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Returning to "; @@ -1619,50 +1824,58 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, } cmState::Snapshot newSnapshot = this->GetState() - ->CreateSnapshot(this->StateSnapshot); + ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot, + this->ContextStack.back()->Name, + this->ContextStack.back()->Line); // create a new local generator and set its parent cmLocalGenerator *lg2 = this->GetGlobalGenerator() ->MakeLocalGenerator(newSnapshot, this->LocalGenerator); this->GetGlobalGenerator()->AddLocalGenerator(lg2); + cmMakefile* subMf = lg2->GetMakefile(); + // set the subdirs start dirs - lg2->GetMakefile()->SetCurrentSourceDirectory(srcPath); - lg2->GetMakefile()->SetCurrentBinaryDirectory(binPath); + subMf->SetCurrentSourceDirectory(srcPath); + subMf->SetCurrentBinaryDirectory(binPath); if(excludeFromAll) { - lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } if (immediate) { - this->ConfigureSubDirectory(lg2); + this->ConfigureSubDirectory(subMf); + } + else + { + this->UnConfiguredDirectories.push_back(subMf); } } void cmMakefile::SetCurrentSourceDirectory(const std::string& dir) { - this->StateSnapshot.SetCurrentSourceDirectory(dir); + this->StateSnapshot.GetDirectory().SetCurrentSource(dir); this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", - this->StateSnapshot.GetCurrentSourceDirectory()); + this->StateSnapshot.GetDirectory().GetCurrentSource()); } const char* cmMakefile::GetCurrentSourceDirectory() const { - return this->StateSnapshot.GetCurrentSourceDirectory(); + return this->StateSnapshot.GetDirectory().GetCurrentSource(); } void cmMakefile::SetCurrentBinaryDirectory(const std::string& dir) { - this->StateSnapshot.SetCurrentBinaryDirectory(dir); - const char* binDir = this->StateSnapshot.GetCurrentBinaryDirectory(); + this->StateSnapshot.GetDirectory().SetCurrentBinary(dir); + const char* binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary(); cmSystemTools::MakeDirectory(binDir); this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", binDir); } const char* cmMakefile::GetCurrentBinaryDirectory() const { - return this->StateSnapshot.GetCurrentBinaryDirectory(); + return this->StateSnapshot.GetDirectory().GetCurrentBinary(); } //---------------------------------------------------------------------------- @@ -1831,7 +2044,7 @@ void cmMakefile::LogUnused(const char* reason, { std::string path; cmListFileContext lfc; - if (!this->CallStack.empty()) + if (!this->ExecutionStatusStack.empty()) { lfc = this->GetExecutionContext(); path = lfc.FilePath; @@ -1843,8 +2056,8 @@ void cmMakefile::LogUnused(const char* reason, lfc.FilePath = path; lfc.Line = 0; } - lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, - cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); if (this->CheckSystemVars || cmSystemTools::IsSubDirectory(path, @@ -1903,11 +2116,26 @@ void cmMakefile::AddGlobalLinkInformation(const std::string& name, return; default:; } - std::vector<std::string>::iterator j; - for(j = this->LinkDirectories.begin(); - j != this->LinkDirectories.end(); ++j) + if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) { - target.AddLinkDirectory(*j); + std::vector<std::string> linkDirs; + cmSystemTools::ExpandListArgument(linkDirsProp, linkDirs); + + for(std::vector<std::string>::iterator j = linkDirs.begin(); + j != linkDirs.end(); ++j) + { + std::string newdir = *j; + // remove trailing slashes + if(*j->rbegin() == '/') + { + newdir = j->substr(0, j->size()-1); + } + if(std::find(this->LinkDirectories.begin(), + this->LinkDirectories.end(), newdir) + == this->LinkDirectories.end()) + {target.AddLinkDirectory(*j); + } + } } target.MergeLinkLibraries( *this, name, this->LinkLibraries ); } @@ -2116,25 +2344,10 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, return; } // build the whole source group path - const char* fullname = sg->GetFullName(); - cmGlobalGenerator* gg = this->GetGlobalGenerator(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } for(++i; i<=lastElement; ++i) { sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName())); sg = sg->LookupChild(name[i].c_str()); - fullname = sg->GetFullName(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } } sg->SetGroupRegex(regex); @@ -2197,19 +2410,19 @@ void cmMakefile::ExpandVariablesCMP0019() } } - for(std::vector<std::string>::iterator d = this->LinkDirectories.begin(); - d != this->LinkDirectories.end(); ++d) + if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) { - if(mightExpandVariablesCMP0019(d->c_str())) + if(mightExpandVariablesCMP0019(linkDirsProp)) { - std::string orig = *d; - this->ExpandVariablesInString(*d, true, true); - if(pol == cmPolicies::WARN && *d != orig) + std::string d = linkDirsProp; + std::string orig = linkDirsProp; + this->ExpandVariablesInString(d, true, true); + if(pol == cmPolicies::WARN && d != orig) { - w << "Evaluated link directory\n" + w << "Evaluated link directories\n" << " " << orig << "\n" << "as\n" - << " " << *d << "\n"; + << " " << d << "\n"; } } } @@ -2390,18 +2603,11 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const return ret; } -std::vector<std::string> cmMakefile -::GetDefinitions(int cacheonly /* = 0 */) const +std::vector<std::string> cmMakefile::GetDefinitions() const { - std::vector<std::string> res; - if ( !cacheonly ) - { - res = this->Internal->ClosureKeys(); - } - std::vector<std::string> cacheKeys = - this->GetState()->GetCacheEntryKeys(); + std::vector<std::string> res = this->Internal->ClosureKeys(); + std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys(); res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); - std::sort(res.begin(), res.end()); return res; } @@ -2763,8 +2969,9 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( { std::ostringstream msg; cmListFileContext lfc; - lfc.FilePath = this->LocalGenerator - ->Convert(filename, cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = + converter.Convert(filename, cmOutputConverter::HOME); lfc.Line = line; msg << "uninitialized variable \'" << lookup << "\'"; this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, @@ -3214,11 +3421,22 @@ bool cmMakefile::IsLoopBlock() const return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0; } +std::string cmMakefile::GetExecutionFilePath() const +{ + assert(this->StateSnapshot.IsValid()); + return this->StateSnapshot.GetExecutionListFile(); +} + //---------------------------------------------------------------------------- bool cmMakefile::ExpandArguments( std::vector<cmListFileArgument> const& inArgs, - std::vector<std::string>& outArgs) const + std::vector<std::string>& outArgs, const char* filename) const { + std::string efp = this->GetExecutionFilePath(); + if (!filename) + { + filename = efp.c_str(); + } std::vector<cmListFileArgument>::const_iterator i; std::string value; outArgs.reserve(inArgs.size()); @@ -3233,8 +3451,7 @@ bool cmMakefile::ExpandArguments( // Expand the variables in the argument. value = i->Value; this->ExpandVariablesInString(value, false, false, false, - i->FilePath, i->Line, - false, false); + filename, i->Line, false, false); // If the argument is quoted, it should be one argument. // Otherwise, it may be a list of arguments. @@ -3253,8 +3470,13 @@ bool cmMakefile::ExpandArguments( //---------------------------------------------------------------------------- bool cmMakefile::ExpandArguments( std::vector<cmListFileArgument> const& inArgs, - std::vector<cmExpandedCommandArgument>& outArgs) const + std::vector<cmExpandedCommandArgument>& outArgs, const char* filename) const { + std::string efp = this->GetExecutionFilePath(); + if (!filename) + { + filename = efp.c_str(); + } std::vector<cmListFileArgument>::const_iterator i; std::string value; outArgs.reserve(inArgs.size()); @@ -3269,8 +3491,7 @@ bool cmMakefile::ExpandArguments( // Expand the variables in the argument. value = i->Value; this->ExpandVariablesInString(value, false, false, false, - i->FilePath, i->Line, - false, false); + filename, i->Line, false, false); // If the argument is quoted, it should be one argument. // Otherwise, it may be a list of arguments. @@ -3294,7 +3515,7 @@ bool cmMakefile::ExpandArguments( //---------------------------------------------------------------------------- void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb) { - if(!this->CallStack.empty()) + if(!this->ExecutionStatusStack.empty()) { // Record the context in which the blocker is created. fb->SetStartingContext(this->GetExecutionContext()); @@ -3327,11 +3548,13 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb, if(!(*pos)->ShouldRemove(lff, *this)) { cmListFileContext const& lfc = fb->GetStartingContext(); + cmListFileContext closingContext = + cmListFileContext::FromCommandContext(lff, lfc.FilePath); std::ostringstream e; e << "A logical block opening on the line\n" << " " << lfc << "\n" << "closes on the line\n" - << " " << lff << "\n" + << " " << closingContext << "\n" << "with mis-matching arguments."; this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); } @@ -3344,19 +3567,6 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb, return cmsys::auto_ptr<cmFunctionBlocker>(); } -//---------------------------------------------------------------------------- -cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf): - Makefile(mf), ReportError(true) -{ - this->Makefile->PushFunctionBlockerBarrier(); -} - -//---------------------------------------------------------------------------- -cmMakefile::LexicalPushPop::~LexicalPushPop() -{ - this->Makefile->PopFunctionBlockerBarrier(this->ReportError); -} - const char* cmMakefile::GetHomeDirectory() const { return this->GetCMakeInstance()->GetHomeDirectory(); @@ -3598,18 +3808,6 @@ cmVariableWatch *cmMakefile::GetVariableWatch() const } #endif -void cmMakefile::AddMacro(const char* name) -{ - assert(name); - this->MacrosList.push_back(name); -} - -void cmMakefile::GetListOfMacros(std::string& macros) const -{ - assert(macros.empty()); - macros = cmJoin(this->MacrosList, ";"); -} - cmState *cmMakefile::GetState() const { return this->GetCMakeInstance()->GetState(); @@ -3919,23 +4117,13 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, void cmMakefile::SetProperty(const std::string& prop, const char* value) { - if ( prop == "LINK_DIRECTORIES" ) - { - std::vector<std::string> varArgsExpanded; - if(value) - { - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - } - this->SetLinkDirectories(varArgsExpanded); - return; - } if (prop == "INCLUDE_DIRECTORIES") { this->IncludeDirectoriesEntries.clear(); - if (!value) - { - return; - } + if (!value) + { + return; + } cmListFileBacktrace lfbt = this->GetBacktrace(); this->IncludeDirectoriesEntries.push_back( cmValueWithOrigin(value, lfbt)); @@ -3944,10 +4132,10 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) if (prop == "COMPILE_OPTIONS") { this->CompileOptionsEntries.clear(); - if (!value) - { - return; - } + if (!value) + { + return; + } cmListFileBacktrace lfbt = this->GetBacktrace(); this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt)); return; @@ -3965,23 +4153,7 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) return; } - if ( prop == "INCLUDE_REGULAR_EXPRESSION" ) - { - this->SetIncludeRegularExpression(value); - return; - } - - if ( prop == "ADDITIONAL_MAKE_CLEAN_FILES" ) - { - // This property is not inherrited - if ( strcmp(this->GetCurrentSourceDirectory(), - this->GetCurrentSourceDirectory()) != 0 ) - { - return; - } - } - - this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY); + this->Properties.SetProperty(prop, value); } void cmMakefile::AppendProperty(const std::string& prop, @@ -4009,85 +4181,54 @@ void cmMakefile::AppendProperty(const std::string& prop, cmValueWithOrigin(value, lfbt)); return; } - if ( prop == "LINK_DIRECTORIES" ) - { - std::vector<std::string> varArgsExpanded; - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin(); - vi != varArgsExpanded.end(); ++vi) - { - this->AddLinkDirectory(*vi); - } - return; - } - this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString); + this->Properties.AppendProperty(prop, value, asString); } const char *cmMakefile::GetProperty(const std::string& prop) const { - return this->GetProperty(prop, cmProperty::DIRECTORY); + const bool chain = this->GetState()-> + IsPropertyChained(prop, cmProperty::DIRECTORY); + return this->GetProperty(prop, chain); } const char *cmMakefile::GetProperty(const std::string& prop, - cmProperty::ScopeType scope) const + bool chain) const { // watch for specific properties static std::string output; output = ""; if (prop == "PARENT_DIRECTORY") { - cmState::Snapshot parent = this->StateSnapshot.GetParent(); + cmState::Snapshot parent = + this->StateSnapshot.GetBuildsystemDirectoryParent(); if(parent.IsValid()) { - return parent.GetCurrentSourceDirectory(); + return parent.GetDirectory().GetCurrentSource(); } return ""; } - else if (prop == "INCLUDE_REGULAR_EXPRESSION" ) - { - output = this->GetIncludeRegularExpression(); - return output.c_str(); - } else if (prop == "LISTFILE_STACK") { - output = cmJoin(this->ListFileStack, ";"); - return output.c_str(); - } - else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES") - { - int cacheonly = 0; - if ( prop == "CACHE_VARIABLES" ) + std::vector<std::string> listFiles; + cmState::Snapshot snp = this->StateSnapshot; + while (snp.IsValid()) { - cacheonly = 1; + listFiles.push_back(snp.GetExecutionListFile()); + snp = snp.GetCallStackParent(); } - output = cmJoin(this->GetDefinitions(cacheonly), ";"); + std::reverse(listFiles.begin(), listFiles.end()); + output = cmJoin(listFiles, ";"); return output.c_str(); } - else if (prop == "MACROS") + else if ( prop == "CACHE_VARIABLES" ) { - this->GetListOfMacros(output); + output = cmJoin(this->GetState()->GetCacheEntryKeys(), ";"); return output.c_str(); } - else if (prop == "DEFINITIONS") - { - switch(this->GetPolicyStatus(cmPolicies::CMP0059)) - { - case cmPolicies::WARN: - this->IssueMessage(cmake::AUTHOR_WARNING, cmPolicies:: - GetPolicyWarning(cmPolicies::CMP0059)); - case cmPolicies::OLD: - output += this->DefineFlagsOrig; - return output.c_str(); - case cmPolicies::NEW: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - break; - } - } - else if (prop == "LINK_DIRECTORIES") + else if (prop == "VARIABLES") { - output = cmJoin(this->GetLinkDirectories(), ";"); + output = cmJoin(this->GetDefinitions(), ";"); return output.c_str(); } else if (prop == "INCLUDE_DIRECTORIES") @@ -4133,15 +4274,13 @@ const char *cmMakefile::GetProperty(const std::string& prop, return output.c_str(); } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, scope, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal && chain) { if(this->LocalGenerator->GetParent()) { return this->LocalGenerator->GetParent()->GetMakefile()-> - GetProperty(prop, scope); + GetProperty(prop, chain); } return this->GetState()->GetGlobalProperty(prop); } @@ -4154,31 +4293,16 @@ bool cmMakefile::GetPropertyAsBool(const std::string& prop) const return cmSystemTools::IsOn(this->GetProperty(prop)); } -//---------------------------------------------------------------------------- -const char* cmMakefile::GetFeature(const std::string& feature, - const std::string& config) +std::vector<std::string> cmMakefile::GetPropertyKeys() const { - // TODO: Define accumulation policy for features (prepend, append, replace). - // Currently we always replace. - if(!config.empty()) + std::vector<std::string> keys; + keys.reserve(this->Properties.size()); + for(cmPropertyMap::const_iterator it = this->Properties.begin(); + it != this->Properties.end(); ++it) { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); - if(const char* value = this->GetProperty(featureConfig)) - { - return value; - } + keys.push_back(it->first); } - if(const char* value = this->GetProperty(feature)) - { - return value; - } - if(cmLocalGenerator* parent = this->LocalGenerator->GetParent()) - { - return parent->GetMakefile()->GetFeature(feature, config); - } - return 0; + return keys; } cmTarget* cmMakefile::FindTarget(const std::string& name, @@ -4253,14 +4377,22 @@ void cmMakefile::AddCMakeDependFilesFromUser() std::string cmMakefile::FormatListFileStack() const { + std::vector<std::string> listFiles; + cmState::Snapshot snp = this->StateSnapshot; + while (snp.IsValid()) + { + listFiles.push_back(snp.GetExecutionListFile()); + snp = snp.GetCallStackParent(); + } + std::reverse(listFiles.begin(), listFiles.end()); std::ostringstream tmp; - size_t depth = this->ListFileStack.size(); + size_t depth = listFiles.size(); if (depth > 0) { - std::vector<std::string>::const_iterator it = this->ListFileStack.end(); + std::vector<std::string>::const_iterator it = listFiles.end(); do { - if (depth != this->ListFileStack.size()) + if (depth != listFiles.size()) { tmp << "\n "; } @@ -4271,7 +4403,7 @@ std::string cmMakefile::FormatListFileStack() const tmp << *it; depth--; } - while (it != this->ListFileStack.begin()); + while (it != listFiles.begin()); } return tmp.str(); } @@ -4596,6 +4728,16 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re) this->MarkVariableAsUsed(nMatchesVariable); } +cmState::Snapshot cmMakefile::GetStateSnapshot() const +{ + return this->StateSnapshot; +} + +const char* cmMakefile::GetDefineFlagsCMP0059() const +{ + return this->DefineFlagsOrig.c_str(); +} + //---------------------------------------------------------------------------- cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const @@ -5357,3 +5499,44 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const } return true; } + + +cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf, + const std::string& fileName, + cmPolicies::PolicyMap const& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushFunctionScope(fileName, pm); +} + +cmMakefile::FunctionPushPop::~FunctionPushPop() +{ + this->Makefile->PopFunctionScope(this->ReportError); +} + + +cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf, + const std::string& fileName, + const cmPolicies::PolicyMap& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushMacroScope(fileName, pm); +} + +cmMakefile::MacroPushPop::~MacroPushPop() +{ + this->Makefile->PopMacroScope(this->ReportError); +} + +cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc, + cmExecutionStatus& status): Makefile(mf) +{ + this->Makefile->ContextStack.push_back(&lfc); + this->Makefile->ExecutionStatusStack.push_back(&status); +} + +cmMakefileCall::~cmMakefileCall() +{ + this->Makefile->ExecutionStatusStack.pop_back(); + this->Makefile->ContextStack.pop_back(); +} |