diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 4380e8f9a..ab48ccf85 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -46,6 +46,7 @@ #include "cmFLTKWrapUICommand.cxx" #include "cmGetFilenameComponentCommand.cxx" #include "cmGetSourceFilePropertyCommand.cxx" +#include "cmITKWrapTclCommand.cxx" #include "cmIfCommand.cxx" #include "cmIncludeCommand.cxx" #include "cmIncludeDirectoryCommand.cxx" @@ -114,6 +115,7 @@ void GetPredefinedCommands(std::list& commands) commands.push_back(new cmFLTKWrapUICommand); commands.push_back(new cmGetFilenameComponentCommand); commands.push_back(new cmGetSourceFilePropertyCommand); + commands.push_back(new cmITKWrapTclCommand); commands.push_back(new cmIfCommand); commands.push_back(new cmIncludeCommand); commands.push_back(new cmIncludeDirectoryCommand); diff --git a/Source/cmITKWrapTclCommand.cxx b/Source/cmITKWrapTclCommand.cxx new file mode 100644 index 000000000..fae71f272 --- /dev/null +++ b/Source/cmITKWrapTclCommand.cxx @@ -0,0 +1,152 @@ +/*========================================================================= + + Program: Insight Segmentation & Registration Toolkit + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Insight Consortium. All rights reserved. + See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmITKWrapTclCommand.h" +#include "cmMakeDepend.h" + +cmITKWrapTclCommand::cmITKWrapTclCommand(): + m_MakeDepend(new cmMakeDepend) +{ +} + +cmITKWrapTclCommand::~cmITKWrapTclCommand() +{ + delete m_MakeDepend; +} + +// cmITKWrapTclCommand +bool cmITKWrapTclCommand::InitialPass(std::vector const& argsIn) +{ + if(argsIn.size() < 2 ) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + std::vector args; + cmSystemTools::ExpandListArguments(argsIn, args); + // keep the target name + m_TargetName = args[0]; + + // Prepare the dependency generator. + m_MakeDepend->SetMakefile(m_Makefile); + + for(std::vector::const_iterator i = (args.begin() + 1); + i != args.end(); ++i) + { + if(!this->CreateCableRule((*i).c_str())) { return false; } + } + + // Add the source list to the target. + m_Makefile->GetTargets()[m_TargetName.c_str()].GetSourceLists().push_back(m_TargetName); + + return true; +} + +bool cmITKWrapTclCommand::CreateCableRule(const char* configFile) +{ + std::string tclFile = + cmSystemTools::GetFilenameNameWithoutExtension(configFile); + tclFile += "_tcl"; + + std::string inFile = m_Makefile->GetCurrentDirectory(); + inFile += "/"; + inFile += configFile; + + std::string outDir = m_Makefile->GetCurrentOutputDirectory(); + + // Generate the rule to run cable to generate wrappers. + std::string command = this->GetCableFromCache(); + std::vector depends; + depends.push_back(command); + std::vector commandArgs; + commandArgs.push_back(inFile); + commandArgs.push_back("-tcl"); + std::string tmp = tclFile+".cxx"; + commandArgs.push_back(tmp); +#if !defined(_WIN32) || defined(__CYGWIN__) + commandArgs.push_back("--gccxml-compiler"); + tmp = "${CXX}"; + m_Makefile->ExpandVariablesInString(tmp); + commandArgs.push_back(tmp); +#endif + tmp = "-I"; + tmp += m_Makefile->GetStartDirectory(); + commandArgs.push_back(tmp); + const std::vector& includes = + m_Makefile->GetIncludeDirectories(); + for(std::vector::const_iterator i = includes.begin(); + i != includes.end(); ++i) + { + tmp = "-I"; + tmp += i->c_str(); + m_Makefile->ExpandVariablesInString(tmp); + commandArgs.push_back(tmp); + } + + // Get the dependencies. + const cmDependInformation* info = + m_MakeDepend->FindDependencies(inFile.c_str()); + if (info) + { + for(cmDependInformation::DependencySet::const_iterator d = + info->m_DependencySet.begin(); + d != info->m_DependencySet.end(); ++d) + { + // Make sure the full path is given. If not, the dependency was + // not found. + if((*d)->m_FullPath != "") + { + depends.push_back((*d)->m_FullPath); + } + } + } + + std::vector outputs; + outputs.push_back(outDir+"/"+tclFile+".cxx"); + + m_Makefile->AddCustomCommand(inFile.c_str(), + command.c_str(), + commandArgs, depends, + outputs, m_TargetName.c_str()); + + // Add the generated source to the package's source list. + cmSourceFile file; + file.SetName(tclFile.c_str(), outDir.c_str(), "cxx", false); + // Set dependency hints. + file.GetDepends().push_back(inFile.c_str()); + file.GetDepends().push_back("CableTclFacility/ctCalls.h"); + m_Makefile->AddSource(file, m_TargetName.c_str()); + + return true; +} + +/** + * Get the "CABLE" cache entry value. If there is no cache entry for CABLE, + * one will be created and initialized to NOTFOUND. + */ +std::string cmITKWrapTclCommand::GetCableFromCache() const +{ + const char* cable = + m_Makefile->GetDefinition("CABLE"); + if(cable) + { return cable; } + + m_Makefile->AddCacheDefinition("CABLE", + "NOTFOUND", + "Path to CABLE executable.", + cmCacheManager::FILEPATH); + return "NOTFOUND"; +} diff --git a/Source/cmITKWrapTclCommand.h b/Source/cmITKWrapTclCommand.h new file mode 100644 index 000000000..6e52ce402 --- /dev/null +++ b/Source/cmITKWrapTclCommand.h @@ -0,0 +1,70 @@ +/*========================================================================= + + Program: Insight Segmentation & Registration Toolkit + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Insight Consortium. All rights reserved. + See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmITKWrapTclCommand_h +#define cmITKWrapTclCommand_h + +#include "cmStandardIncludes.h" +#include "cmCommand.h" + +class cmMakeDepend; + +/** \class cmITKWrapTclCommand + * \brief Run CABLE to generate Tcl wrappers. + * + * cmITKWrapTclCommand runs CABLE on the specified configuration files + * and combines them into a package on a given target. + */ +class cmITKWrapTclCommand : public cmCommand +{ +public: + cmITKWrapTclCommand(); + ~cmITKWrapTclCommand(); + + /** This is a virtual constructor for the command. */ + virtual cmCommand* Clone() { return new cmITKWrapTclCommand; } + + /** This is called when the command is first encountered in + * the CMakeLists.txt file. */ + virtual bool InitialPass(std::vector const& args); + + /** The name of the command as specified in CMakeList.txt. */ + virtual const char* GetName() {return "ITK_WRAP_TCL";} + + /** Succinct documentation. */ + virtual const char* GetTerseDocumentation() + { return "Run CABLE to generate Tcl wrappers."; } + + /** More documentation. */ + virtual const char* GetFullDocumentation() + { + return + "ITK_WRAP_TCL(target-name config-file1 [config-file2 ...])\n" + "Run CABLE on all the configuration files to generate Tcl wrappers.\n" + "The generated sources are added to a target of the given name."; + } + + cmTypeMacro(cmITKWrapTclCommand, cmCommand); +protected: + cmStdString m_TargetName; + + bool CreateCableRule(const char* configFile); + std::string GetCableFromCache() const; + + cmMakeDepend* m_MakeDepend; +}; + +#endif