diff options
Diffstat (limited to 'Source/cmMakefile.cxx')
-rw-r--r-- | Source/cmMakefile.cxx | 297 |
1 files changed, 271 insertions, 26 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a71de1b..661841b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -65,6 +65,7 @@ cmMakefile::cmMakefile() this->AddSourceGroup("Source Files", "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$"); this->AddSourceGroup("Header Files", "\\.(h|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"); + this->AddSourceGroup("CMake Rules", "\\.rule$"); this->AddDefaultDefinitions(); } @@ -169,7 +170,7 @@ void cmMakefile::Print() const for( std::vector<cmSourceGroup>::const_iterator i = m_SourceGroups.begin(); i != m_SourceGroups.end(); ++i) { - i->Print(); + std::cout << "Source Group: " << i->GetName() << std::endl; } } @@ -441,6 +442,7 @@ void cmMakefile::ConfigureFinalPass() } +// this is the old style signature, we convert to new style void cmMakefile::AddCustomCommand(const char* source, const char* command, const std::vector<std::string>& commandArgs, @@ -449,13 +451,137 @@ void cmMakefile::AddCustomCommand(const char* source, const char *target, const char *comment) { + if (strcmp(source,target)) + { + // what a pain, for backwards compatibility we will try to + // convert this to an output based rule... so for each output.. + for(std::vector<std::string>::const_iterator d = outputs.begin(); + d != outputs.end(); ++d) + { + this->AddCustomCommandToOutput(d->c_str(), command, commandArgs, + source, depends, comment); + // add the output to the target? + std::string sname = *d; + sname += ".rule"; + if (!this->GetSource(sname.c_str())) + { + m_Targets[target].GetSourceLists().push_back(source); + } + } + } + else + { + this->AddCustomCommandToTarget(target, command, commandArgs, + cmTarget::POST_BUILD, + comment); + } +} + +void cmMakefile::AddCustomCommand(const char* source, + const char* command, + const std::vector<std::string>& commandArgs, + const std::vector<std::string>& depends, + const char* output, + const char *target) +{ + std::vector<std::string> outputs; + outputs.push_back(output); + this->AddCustomCommand(source, command, commandArgs, depends, + outputs, target); +} + +void cmMakefile:: +AddCustomCommandToOutput(const char* output, + const char* command, + const std::vector<std::string>& commandArgs, + const char *main_dependency, + const std::vector<std::string>& depends, + const char *comment, + bool replace) +{ + cmSourceFile *file = 0; + std::string outName = output; + outName += ".rule"; + + // OK this rule will be placed on a generated output file unless the main + // depednency was specified. + if (main_dependency && main_dependency[0] != '\0') + { + file = this->GetSource(main_dependency); + if (file && file->GetCustomCommand() && !replace) + { + // generate a source instead + file = 0; + } + else + { + file = this->GetOrCreateSource(main_dependency); + } + } + + if (!file) + { + file = this->GetSource(outName.c_str()); + if (file && file->GetCustomCommand() && !replace) + { + cmSystemTools::Error("Attempt to add a custom rule to an output that already has a custom rule. For output: ", output); + return; + } + // create a cmSourceFile for the output + file = this->GetOrCreateSource(outName.c_str(), true); + // always mark as generated + file->SetProperty("GENERATED","1"); + } + + // always create the output and mark it generated + cmSourceFile *out = this->GetOrCreateSource(output, true); + out->SetProperty("GENERATED","1"); + + // process the command + std::string expandC = command; + this->ExpandVariablesInString(expandC); + std::string c = cmSystemTools::EscapeSpaces(expandC.c_str()); + + std::string combinedArgs; + unsigned int i; + for (i = 0; i < commandArgs.size(); ++i) + { + expandC = commandArgs[i].c_str(); + this->ExpandVariablesInString(expandC); + combinedArgs += cmSystemTools::EscapeSpaces(expandC.c_str()); + combinedArgs += " "; + } + std::vector<std::string> depends2(depends); + if (main_dependency && main_dependency[0] != '\0') + { + depends2.push_back(main_dependency); + } + cmCustomCommand *cc = + new cmCustomCommand(c.c_str(),combinedArgs.c_str(),depends2, output); + if ( comment && comment[0] ) + { + cc->SetComment(comment); + } + if (file->GetCustomCommand()) + { + delete file->GetCustomCommand(); + } + file->SetCustomCommand(cc); +} + +void cmMakefile:: +AddCustomCommandToTarget(const char* target, const char* command, + const std::vector<std::string>& commandArgs, + cmTarget::CustomCommandType type, + const char *comment) +{ // find the target, if (m_Targets.find(target) != m_Targets.end()) { std::string expandC = command; this->ExpandVariablesInString(expandC); std::string c = cmSystemTools::EscapeSpaces(expandC.c_str()); - + std::string combinedArgs; unsigned int i; @@ -467,12 +593,23 @@ void cmMakefile::AddCustomCommand(const char* source, combinedArgs += " "; } - cmCustomCommand cc(source,c.c_str(),combinedArgs.c_str(),depends,outputs); + cmCustomCommand cc(c.c_str(),combinedArgs.c_str()); if ( comment && comment[0] ) { cc.SetComment(comment); } - m_Targets[target].GetCustomCommands().push_back(cc); + switch (type) + { + case cmTarget::PRE_BUILD: + m_Targets[target].GetPreBuildCommands().push_back(cc); + break; + case cmTarget::PRE_LINK: + m_Targets[target].GetPreLinkCommands().push_back(cc); + break; + case cmTarget::POST_BUILD: + m_Targets[target].GetPostBuildCommands().push_back(cc); + break; + } std::string cacheCommand = command; this->ExpandVariablesInString(cacheCommand); if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str())) @@ -483,18 +620,6 @@ void cmMakefile::AddCustomCommand(const char* source, } } -void cmMakefile::AddCustomCommand(const char* source, - const char* command, - const std::vector<std::string>& commandArgs, - const std::vector<std::string>& depends, - const char* output, - const char *target) -{ - std::vector<std::string> outputs; - outputs.push_back(output); - this->AddCustomCommand(source, command, commandArgs, depends, outputs, target); -} - void cmMakefile::AddDefineFlag(const char* flag) { m_DefineFlags += " "; @@ -799,11 +924,12 @@ void cmMakefile::AddExecutable(const char *exeName, void cmMakefile::AddUtilityCommand(const char* utilityName, const char* command, const char* arguments, - bool all) + bool all, + const std::vector<std::string> &depends) { std::vector<std::string> empty; this->AddUtilityCommand(utilityName,command,arguments,all, - empty,empty); + depends, empty); } void cmMakefile::AddUtilityCommand(const char* utilityName, @@ -816,11 +942,54 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, cmTarget target; target.SetType(cmTarget::UTILITY); target.SetInAll(all); - cmCustomCommand cc(utilityName, command, arguments, dep, out); - target.GetCustomCommands().push_back(cc); + if (out.size() > 1) + { + cmSystemTools::Error( + "Utility targets can only have one output. For utilityNamed: ", + utilityName); + return; + } + if (out.size()) + { + cmCustomCommand cc(command, arguments, dep, out[0].c_str()); + target.GetPostBuildCommands().push_back(cc); + } + else + { + cmCustomCommand cc(command, arguments, dep, NULL); + target.GetPostBuildCommands().push_back(cc); + } m_Targets.insert(cmTargets::value_type(utilityName,target)); } +cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname) +{ + std::string name = cname; + + // look through all the source files that have custom commands + // and see if the custom command has the passed source file as an output + // keep in mind the possible .rule extension that may be tacked on + for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin(); + i != m_SourceFiles.end(); ++i) + { + // does this source file have a custom command? + if ((*i)->GetCustomCommand()) + { + // is the output of the custom command match the source files name + std::string out = (*i)->GetCustomCommand()->GetOutput(); + if (out.rfind(name) != out.npos && + out.rfind(name) == out.size() - name.size()) + { + return *i; + } + } + } + + // otherwise return NULL + return NULL; +} + + cmSourceGroup* cmMakefile::GetSourceGroup(const char* name) { // First see if the group exists. If so, replace its regular expression. @@ -946,6 +1115,19 @@ void cmMakefile::ExpandVariables() } } +void cmMakefile::ExpandVariablesInCustomCommands() +{ + for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin(); + i != m_SourceFiles.end(); ++i) + { + cmCustomCommand *cc = (*i)->GetCustomCommand(); + if (cc) + { + cc->ExpandVariables(*this); + } + } +} + bool cmMakefile::IsOn(const char* name) const { const char* value = this->GetDefinition(name); @@ -1254,7 +1436,7 @@ cmMakefile::FindSourceGroup(const char* source, std::string::size_type pos = file.rfind('/'); if(pos != std::string::npos) { - file = file.substr(pos, file.length()-pos); + file = file.substr(pos+1); } for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin(); @@ -1402,11 +1584,11 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName) const { std::string s = cmSystemTools::GetFilenameName(sourceName); std::string ext; - std::string::size_type pos = s.rfind('.'); - if(pos != std::string::npos) + ext = cmSystemTools::GetFilenameLastExtension(s); + s = s.substr(0, s.length()-ext.length()); + if ( ext.length() && ext[0] == '.' ) { - ext = s.substr(pos+1, s.size() - pos-1); - s = s.substr(0, pos); + ext = ext.substr(1); } for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin(); i != m_SourceFiles.end(); ++i) @@ -1422,8 +1604,71 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName) const return 0; } +cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName, + bool generated) +{ + // check to see if it exists + cmSourceFile* ret = this->GetSource(sourceName); + if (ret) + { + return ret; + } + + // we must create one + std::string newfile = sourceName; + cmSourceFile file; + std::string path = cmSystemTools::GetFilenamePath(newfile); + if(generated) + { + std::string ext = cmSystemTools::GetFilenameLastExtension(newfile); + std::string name_no_ext = cmSystemTools::GetFilenameName(newfile.c_str()); + name_no_ext = name_no_ext.substr(0, name_no_ext.length()-ext.length()); + if ( ext.length() && ext[0] == '.' ) + { + ext = ext.substr(1); + } + if((path.size() && path[0] == '/') || + (path.size() > 1 && path[1] == ':')) + { + file.SetName(name_no_ext.c_str(), path.c_str(), ext.c_str(), false); + } + else + { + file.SetName(name_no_ext.c_str(), this->GetCurrentOutputDirectory(), + ext.c_str(), false); + } + } + else + { + // if this is a full path then + if((path.size() && path[0] == '/') || + (path.size() > 1 && path[1] == ':')) + { + file.SetName(cmSystemTools::GetFilenameName(newfile.c_str()).c_str(), + path.c_str(), + this->GetSourceExtensions(), + this->GetHeaderExtensions()); + } + else + { + file.SetName(newfile.c_str(), this->GetCurrentDirectory(), + this->GetSourceExtensions(), + this->GetHeaderExtensions()); + } + } + // add the source file to the makefile + this->AddSource(file); + ret = this->GetSource(sourceName); + if (!ret) + { + cmSystemTools::Error( + "CMake failed to properly look up cmSourceFile: ", sourceName); + int i = *(int *)0x0; + } + return ret; +} - + cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf) { // check to see if it exists |