From d7a5d4c191b503f0d30abf9fbf0672370157c430 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 17 Sep 2007 10:50:46 -0400 Subject: ENH: Added IMPLICIT_DEPENDS option to ADD_CUSTOM_COMMAND. It currently works only for Makefile generators. It allows a custom command to have implicit dependencies in the form of C or CXX sources. --- Source/cmAddCustomCommandCommand.cxx | 52 ++++++++++++++++++++++++++++++++++++ Source/cmAddCustomCommandCommand.h | 10 +++++++ Source/cmCustomCommand.cxx | 20 ++++++++++++++ Source/cmCustomCommand.h | 7 +++++ Source/cmMakefileTargetGenerator.cxx | 15 +++++++++++ 5 files changed, 104 insertions(+) diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index a55c7e8..6bff7c1 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -40,6 +40,8 @@ bool cmAddCustomCommandCommand::InitialPass( std::vector depends, outputs, output; bool verbatim = false; bool append = false; + std::string implicit_depends_lang; + cmCustomCommand::ImplicitDependsList implicit_depends; // Accumulate one command line at a time. cmCustomCommandLine currentLine; @@ -54,6 +56,8 @@ bool cmAddCustomCommandCommand::InitialPass( doing_command, doing_target, doing_depends, + doing_implicit_depends_lang, + doing_implicit_depends_file, doing_main_dependency, doing_output, doing_outputs, @@ -131,6 +135,10 @@ bool cmAddCustomCommandCommand::InitialPass( { doing = doing_main_dependency; } + else if (copy == "IMPLICIT_DEPENDS") + { + doing = doing_implicit_depends_lang; + } else if (copy == "COMMENT") { doing = doing_comment; @@ -173,6 +181,25 @@ bool cmAddCustomCommandCommand::InitialPass( case doing_main_dependency: main_dependency = copy; break; + case doing_implicit_depends_lang: + implicit_depends_lang = copy; + doing = doing_implicit_depends_file; + break; + case doing_implicit_depends_file: + { + // An implicit dependency starting point is also an + // explicit dependency. + depends.push_back(copy); + + // Add the implicit dependency language and file. + cmCustomCommand::ImplicitDependsPair + entry(implicit_depends_lang, copy); + implicit_depends.push_back(entry); + + // Switch back to looking for a language. + doing = doing_implicit_depends_lang; + } + break; case doing_command: currentLine.push_back(copy); break; @@ -240,6 +267,7 @@ bool cmAddCustomCommandCommand::InitialPass( { cc->AppendCommands(commandLines); cc->AppendDepends(depends); + cc->AppendImplicitDepends(implicit_depends); return true; } } @@ -271,6 +299,29 @@ bool cmAddCustomCommandCommand::InitialPass( commandLines, comment, working.c_str(), false, escapeOldStyle); + + // Add implicit dependency scanning requests if any were given. + if(!implicit_depends.empty()) + { + bool okay = false; + if(cmSourceFile* sf = + this->Makefile->GetSourceFileWithOutput(output[0].c_str())) + { + if(cmCustomCommand* cc = sf->GetCustomCommand()) + { + okay = true; + cc->SetImplicitDepends(implicit_depends); + } + } + if(!okay) + { + cmOStringStream e; + e << "could not locate source file with a custom command producing \"" + << output[0] << "\" even though this command tried to create it!"; + this->SetError(e.str().c_str()); + return false; + } + } } else { @@ -279,6 +330,7 @@ bool cmAddCustomCommandCommand::InitialPass( source.c_str(), commandLines, comment); } + return true; } diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index e2bf2f1..845c594 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -71,6 +71,7 @@ public: " [COMMAND command2 [ARGS] [args2...] ...]\n" " [MAIN_DEPENDENCY depend]\n" " [DEPENDS [depends...]]\n" + " [IMPLICIT_DEPENDS depend1 ...]\n" " [WORKING_DIRECTORY dir]\n" " [COMMENT comment] [VERBATIM] [APPEND])\n" "This defines a new command that can be executed during the build " @@ -129,6 +130,15 @@ public: "created as a file on disk it should be marked as SYMBOLIC with " "SET_SOURCE_FILES_PROPERTIES.\n" + "The IMPLICIT_DEPENDS option requests scanning of implicit " + "dependencies of an input file. The language given specifies the " + "programming language whose corresponding dependency scanner should " + "be used. Currently only C and CXX language scanners are supported. " + "Dependencies discovered from the scanning are added to those of " + "the custom command at build time. Note that the IMPLICIT_DEPENDS " + "option is currently supported only for Makefile generators and " + "will be ignored by other generators." + "\n" "If COMMAND specifies an executable target (created by " "ADD_EXECUTABLE) it will automatically be replaced by the location " "of the executable created at build time. Additionally a " diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index b0df423..60896b1 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -134,3 +134,23 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b) { this->EscapeAllowMakeVars = b; } + +//---------------------------------------------------------------------------- +cmCustomCommand::ImplicitDependsList const& +cmCustomCommand::GetImplicitDepends() const +{ + return this->ImplicitDepends; +} + +//---------------------------------------------------------------------------- +void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l) +{ + this->ImplicitDepends = l; +} + +//---------------------------------------------------------------------------- +void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l) +{ + this->ImplicitDepends.insert(this->ImplicitDepends.end(), + l.begin(), l.end()); +} diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 17b4c0d..70319e5 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -68,6 +68,12 @@ public: bool GetEscapeAllowMakeVars() const; void SetEscapeAllowMakeVars(bool b); + typedef std::pair ImplicitDependsPair; + class ImplicitDependsList: public std::vector {}; + void SetImplicitDepends(ImplicitDependsList const&); + void AppendImplicitDepends(ImplicitDependsList const&); + ImplicitDependsList const& GetImplicitDepends() const; + private: std::vector Outputs; std::vector Depends; @@ -77,6 +83,7 @@ private: std::string WorkingDirectory; bool EscapeAllowMakeVars; bool EscapeOldStyle; + ImplicitDependsList ImplicitDepends; }; #endif diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index b2b3fa1..569d761 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -939,6 +939,21 @@ void cmMakefileTargetGenerator } this->GenerateExtraOutput(o->c_str(), in, symbolic); } + + // Setup implicit dependency scanning. + for(cmCustomCommand::ImplicitDependsList::const_iterator + idi = cc.GetImplicitDepends().begin(); + idi != cc.GetImplicitDepends().end(); ++idi) + { + std::string objFullPath = + this->Convert(outputs[0].c_str(), cmLocalGenerator::FULL); + std::string srcFullPath = + this->Convert(idi->second.c_str(), cmLocalGenerator::FULL); + this->LocalGenerator-> + AddImplicitDepends(*this->Target, idi->first.c_str(), + objFullPath.c_str(), + srcFullPath.c_str()); + } } //---------------------------------------------------------------------------- -- cgit v0.12