diff options
author | Brad King <brad.king@kitware.com> | 2006-04-11 15:06:19 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2006-04-11 15:06:19 (GMT) |
commit | d5719f22c1dca3e100f1e3b5dfaa4fe7d26796a0 (patch) | |
tree | 714a99bed97290f96ff8f846fa6864cebbdc0a28 /Source/cmAddCustomCommandCommand.cxx | |
parent | b613cf0be806cc1d37d2b590f1a5ba7898236ae8 (diff) | |
download | CMake-d5719f22c1dca3e100f1e3b5dfaa4fe7d26796a0.zip CMake-d5719f22c1dca3e100f1e3b5dfaa4fe7d26796a0.tar.gz CMake-d5719f22c1dca3e100f1e3b5dfaa4fe7d26796a0.tar.bz2 |
ENH: Added support for multiple outputs generated by a single custom command. For Visual Studio generators the native tool provides support. For Xcode and Makefile generators a simple trick is used. The first output is considered primary and has the build rule attached. Other outputs simply depend on the first output with no build rule. During cmake_check_build_system CMake detects when a secondary output is missing and removes the primary output to make sure all outputs are regenerated. This approach always builds the custom command at the right time and only once even during parallel builds.
Diffstat (limited to 'Source/cmAddCustomCommandCommand.cxx')
-rw-r--r-- | Source/cmAddCustomCommandCommand.cxx | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index a9f948c..4f6df9e 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -32,9 +32,9 @@ bool cmAddCustomCommandCommand::InitialPass( return false; } - std::string source, target, comment, output, main_dependency, + std::string source, target, comment, main_dependency, working; - std::vector<std::string> depends, outputs; + std::vector<std::string> depends, outputs, output; // Accumulate one command line at a time. cmCustomCommandLine currentLine; @@ -155,7 +155,7 @@ bool cmAddCustomCommandCommand::InitialPass( source = copy; break; case doing_output: - output = filename; + output.push_back(filename); break; case doing_main_dependency: main_dependency = copy; @@ -204,34 +204,9 @@ bool cmAddCustomCommandCommand::InitialPass( return false; } - if ( !this->Makefile->CanIWriteThisFile(output.c_str()) ) + // Make sure the output names and locations are safe. + if(!this->CheckOutputs(output) || !this->CheckOutputs(outputs)) { - std::string e = "attempted to have a file: " + output + - " in a source directory as an output of custom command."; - this->SetError(e.c_str()); - cmSystemTools::SetFatalErrorOccured(); - return false; - } - std::vector<std::string>::iterator oit; - for ( oit = outputs.begin(); oit != outputs.end(); ++ oit ) - { - if ( !this->Makefile->CanIWriteThisFile(oit->c_str()) ) - { - std::string e = "attempted to have a file: " + *oit + - " in a source directory as an output of custom command."; - this->SetError(e.c_str()); - cmSystemTools::SetFatalErrorOccured(); - return false; - } - } - - std::string::size_type pos = output.find_first_of("#<>"); - if(pos != output.npos) - { - cmOStringStream msg; - msg << "called with OUTPUT containing a \"" << output[pos] - << "\". This character is not allowed."; - this->SetError(msg.str().c_str()); return false; } @@ -247,7 +222,7 @@ bool cmAddCustomCommandCommand::InitialPass( else if(target.empty()) { // Target is empty, use the output. - this->Makefile->AddCustomCommandToOutput(output.c_str(), depends, + this->Makefile->AddCustomCommandToOutput(output, depends, main_dependency.c_str(), commandLines, comment.c_str(), working.c_str()); @@ -261,3 +236,36 @@ bool cmAddCustomCommandCommand::InitialPass( } return true; } + +//---------------------------------------------------------------------------- +bool +cmAddCustomCommandCommand +::CheckOutputs(const std::vector<std::string>& outputs) +{ + for(std::vector<std::string>::const_iterator o = outputs.begin(); + o != outputs.end(); ++o) + { + // Make sure the file will not be generated into the source + // directory during an out of source build. + if(!this->Makefile->CanIWriteThisFile(o->c_str())) + { + std::string e = "attempted to have a file \"" + *o + + "\" in a source directory as an output of custom command."; + this->SetError(e.c_str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + // Make sure the output file name has no invalid characters. + std::string::size_type pos = o->find_first_of("#<>"); + if(pos != o->npos) + { + cmOStringStream msg; + msg << "called with OUTPUT containing a \"" << (*o)[pos] + << "\". This character is not allowed."; + this->SetError(msg.str().c_str()); + return false; + } + } + return true; +} |