Browse Source

ENH: implement ADD_TARGET command, and add an ALL_BUILD target

Bill Hoffman 24 years ago
parent
commit
96ec40943c

+ 5 - 8
Source/cmAddTargetCommand.cxx

@@ -43,17 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // cmAddTargetCommand
 bool cmAddTargetCommand::Invoke(std::vector<std::string>& args)
 {
-  if(args.size() < 1 )
+  if(args.size() < 2 )
     {
     this->SetError("called with incorrect number of arguments");
     return false;
     }
-  return false;
-  
-//    for(std::vector<std::string>::iterator i = args.begin();
-//        i != args.end(); ++i)
-//      {
-//      m_Makefile->Add((*i).c_str());
-//      }
+  std::vector<std::string> dep;
+  m_Makefile->AddUtilityCommand(args[0].c_str(), 
+                                args[1].c_str());
+  return true;
 }
 

+ 73 - 10
Source/cmDSPMakefile.cxx

@@ -92,13 +92,17 @@ void cmDSPMakefile::OutputDSPFile()
   for(cmTargets::iterator l = tgts.begin(); 
       l != tgts.end(); l++)
     {
-    if (l->second.IsALibrary())
+    switch(l->second.GetType())
       {
-      this->SetBuildType(m_LibraryBuildType, l->first.c_str());
-      }
-    else
-      {
-      this->SetBuildType(EXECUTABLE,l->first.c_str());
+      case cmTarget::LIBRARY:
+        this->SetBuildType(m_LibraryBuildType, l->first.c_str());
+        break;
+      case cmTarget::EXECUTABLE:
+        this->SetBuildType(EXECUTABLE,l->first.c_str());
+        break;
+      case cmTarget::UTILITY:
+        this->SetBuildType(UTILITY, l->first.c_str());
+        break;
       }
     this->CreateSingleDSP(l->first.c_str(),l->second);
     }
@@ -121,6 +125,39 @@ void cmDSPMakefile::CreateSingleDSP(const char *lname, cmTarget &target)
   this->WriteDSPFile(fout,lname,target);
 }
 
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
+{
+  std::string dspname = *(m_CreatedProjectNames.end()-1);
+  dspname += ".dsp";
+  std::string makefileIn = "\"";
+  makefileIn += m_Makefile->GetStartDirectory();
+  makefileIn += "/";
+  makefileIn += "CMakeLists.txt\"";
+  std::string dsprule = "\"";
+  dsprule += m_Makefile->GetHomeDirectory();
+  dsprule += "/CMake/Source/CMakeSetupCMD\" ";
+  dsprule += makefileIn;
+  dsprule += " -DSP -H\"";
+  dsprule += m_Makefile->GetHomeDirectory();
+  dsprule += "\" -S\"";
+  dsprule += m_Makefile->GetStartDirectory();
+  dsprule += "\" -O\"";
+  dsprule += m_Makefile->GetStartOutputDirectory();
+  dsprule += "\" -B\"";
+  dsprule += m_Makefile->GetHomeOutputDirectory();
+  dsprule += "\"";
+
+  std::set<std::string> depends;
+  std::set<std::string> outputs;
+  outputs.insert(outputs.begin(), dspname);
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" << makefileIn.c_str() << "\n\n";
+  this->WriteCustomRule(fout, makefileIn.c_str(), dsprule.c_str(), depends, outputs);
+  fout << "# End Source File\n";
+}
+
+
 void cmDSPMakefile::AddDSPBuildRule(cmSourceGroup& sourceGroup)
 {
   std::string dspname = *(m_CreatedProjectNames.end()-1);
@@ -230,7 +267,7 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
 
       // Tell MS-Dev what the source is.  If the compiler knows how to
       // build it, then it will.
-      fout << "SOURCE=" << source << "\n\n";
+      fout << "SOURCE=" << source.c_str() << "\n\n";
       
       // Loop through every custom command generating code from the
       // current source.
@@ -239,8 +276,21 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
         {
         std::string command = c->first;
         const cmSourceGroup::CommandFiles& commandFiles = c->second;
-        this->WriteCustomRule(fout, command.c_str(), commandFiles.m_Depends,
+        this->WriteCustomRule(fout, source.c_str(), command.c_str(), commandFiles.m_Depends,
                               commandFiles.m_Outputs);
+        // Create a dummy file with the name of the source if it does
+        // not exist
+        if(commandFiles.m_Outputs.size() == 0)
+          { 
+          std::string dummyFile = m_Makefile->GetStartOutputDirectory();
+          dummyFile += "/";
+          dummyFile += source;
+          if(!cmSystemTools::FileExists(dummyFile.c_str()))
+            {
+            std::ofstream fout(dummyFile.c_str());
+            fout << "Dummy file created by cmake as unused source for utility command.\n";
+            }
+          }
         }      
       
       fout << "# End Source File\n";
@@ -259,6 +309,7 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
 
 
 void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
+                                    const char* source,
                                     const char* command,
                                     const std::set<std::string>& depends,
                                     const std::set<std::string>& outputs)
@@ -274,7 +325,8 @@ void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
       {
       fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
       }
-
+    fout << "# Begin Custom Build\n\n";
+    
     // Write out the dependencies (this seems to be the only way to
     //  get VC6 to actually take these dependencies into account.
     fout << "USERDEP__HACK= ";
@@ -286,6 +338,11 @@ void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
     fout << "\n";
 
     fout << "# Begin Custom Build\n\n";
+    if(outputs.size() == 0)
+      {
+      fout << source << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
+      fout << "\n  " << command << "\n\n";
+      }
     
     // Write a rule for every output generated by this command.
     for(std::set<std::string>::const_iterator output = outputs.begin();
@@ -348,6 +405,12 @@ void cmDSPMakefile::SetBuildType(BuildType b, const char *libName)
       m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
       m_DSPFooterTemplate += "/CMake/Source/EXEFooter.dsptemplate";
       break;
+    case UTILITY:
+      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
+      m_DSPHeaderTemplate += "/CMake/Source/UtilityHeader.dsptemplate";
+      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
+      m_DSPFooterTemplate += "/CMake/Source/UtilityFooter.dsptemplate";
+      break;
     }
 
   // once the build type is set, determine what configurations are
@@ -400,7 +463,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout, const char *libName,
     {
     // add libraries to executables and dlls (but never include
     // a library in a library, bad recursion)
-    if (!target.IsALibrary() || 
+    if (!target.GetType() == cmTarget::LIBRARY || 
         (m_LibraryBuildType == DLL && libName != j->first))
       {
       if (j->second == cmTarget::GENERAL)

+ 2 - 1
Source/cmDSPMakefile.h

@@ -57,7 +57,7 @@ public:
   cmDSPMakefile(cmMakefile*);
   ~cmDSPMakefile();
   void OutputDSPFile();
-  enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE};
+  enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE, UTILITY};
 
   /**
    * Specify the type of the build: static, dll, or executable.
@@ -107,6 +107,7 @@ private:
   void WriteDSPFooter(std::ostream& fout);
   void AddDSPBuildRule(cmSourceGroup&);
   void WriteCustomRule(std::ostream& fout,
+                       const char* source,
                        const char* command,
                        const std::set<std::string>& depends,
                        const std::set<std::string>& outputs);

+ 73 - 10
Source/cmDSPWriter.cxx

@@ -92,13 +92,17 @@ void cmDSPMakefile::OutputDSPFile()
   for(cmTargets::iterator l = tgts.begin(); 
       l != tgts.end(); l++)
     {
-    if (l->second.IsALibrary())
+    switch(l->second.GetType())
       {
-      this->SetBuildType(m_LibraryBuildType, l->first.c_str());
-      }
-    else
-      {
-      this->SetBuildType(EXECUTABLE,l->first.c_str());
+      case cmTarget::LIBRARY:
+        this->SetBuildType(m_LibraryBuildType, l->first.c_str());
+        break;
+      case cmTarget::EXECUTABLE:
+        this->SetBuildType(EXECUTABLE,l->first.c_str());
+        break;
+      case cmTarget::UTILITY:
+        this->SetBuildType(UTILITY, l->first.c_str());
+        break;
       }
     this->CreateSingleDSP(l->first.c_str(),l->second);
     }
@@ -121,6 +125,39 @@ void cmDSPMakefile::CreateSingleDSP(const char *lname, cmTarget &target)
   this->WriteDSPFile(fout,lname,target);
 }
 
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
+{
+  std::string dspname = *(m_CreatedProjectNames.end()-1);
+  dspname += ".dsp";
+  std::string makefileIn = "\"";
+  makefileIn += m_Makefile->GetStartDirectory();
+  makefileIn += "/";
+  makefileIn += "CMakeLists.txt\"";
+  std::string dsprule = "\"";
+  dsprule += m_Makefile->GetHomeDirectory();
+  dsprule += "/CMake/Source/CMakeSetupCMD\" ";
+  dsprule += makefileIn;
+  dsprule += " -DSP -H\"";
+  dsprule += m_Makefile->GetHomeDirectory();
+  dsprule += "\" -S\"";
+  dsprule += m_Makefile->GetStartDirectory();
+  dsprule += "\" -O\"";
+  dsprule += m_Makefile->GetStartOutputDirectory();
+  dsprule += "\" -B\"";
+  dsprule += m_Makefile->GetHomeOutputDirectory();
+  dsprule += "\"";
+
+  std::set<std::string> depends;
+  std::set<std::string> outputs;
+  outputs.insert(outputs.begin(), dspname);
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" << makefileIn.c_str() << "\n\n";
+  this->WriteCustomRule(fout, makefileIn.c_str(), dsprule.c_str(), depends, outputs);
+  fout << "# End Source File\n";
+}
+
+
 void cmDSPMakefile::AddDSPBuildRule(cmSourceGroup& sourceGroup)
 {
   std::string dspname = *(m_CreatedProjectNames.end()-1);
@@ -230,7 +267,7 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
 
       // Tell MS-Dev what the source is.  If the compiler knows how to
       // build it, then it will.
-      fout << "SOURCE=" << source << "\n\n";
+      fout << "SOURCE=" << source.c_str() << "\n\n";
       
       // Loop through every custom command generating code from the
       // current source.
@@ -239,8 +276,21 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
         {
         std::string command = c->first;
         const cmSourceGroup::CommandFiles& commandFiles = c->second;
-        this->WriteCustomRule(fout, command.c_str(), commandFiles.m_Depends,
+        this->WriteCustomRule(fout, source.c_str(), command.c_str(), commandFiles.m_Depends,
                               commandFiles.m_Outputs);
+        // Create a dummy file with the name of the source if it does
+        // not exist
+        if(commandFiles.m_Outputs.size() == 0)
+          { 
+          std::string dummyFile = m_Makefile->GetStartOutputDirectory();
+          dummyFile += "/";
+          dummyFile += source;
+          if(!cmSystemTools::FileExists(dummyFile.c_str()))
+            {
+            std::ofstream fout(dummyFile.c_str());
+            fout << "Dummy file created by cmake as unused source for utility command.\n";
+            }
+          }
         }      
       
       fout << "# End Source File\n";
@@ -259,6 +309,7 @@ void cmDSPMakefile::WriteDSPFile(std::ostream& fout,
 
 
 void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
+                                    const char* source,
                                     const char* command,
                                     const std::set<std::string>& depends,
                                     const std::set<std::string>& outputs)
@@ -274,7 +325,8 @@ void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
       {
       fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
       }
-
+    fout << "# Begin Custom Build\n\n";
+    
     // Write out the dependencies (this seems to be the only way to
     //  get VC6 to actually take these dependencies into account.
     fout << "USERDEP__HACK= ";
@@ -286,6 +338,11 @@ void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
     fout << "\n";
 
     fout << "# Begin Custom Build\n\n";
+    if(outputs.size() == 0)
+      {
+      fout << source << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
+      fout << "\n  " << command << "\n\n";
+      }
     
     // Write a rule for every output generated by this command.
     for(std::set<std::string>::const_iterator output = outputs.begin();
@@ -348,6 +405,12 @@ void cmDSPMakefile::SetBuildType(BuildType b, const char *libName)
       m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
       m_DSPFooterTemplate += "/CMake/Source/EXEFooter.dsptemplate";
       break;
+    case UTILITY:
+      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
+      m_DSPHeaderTemplate += "/CMake/Source/UtilityHeader.dsptemplate";
+      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
+      m_DSPFooterTemplate += "/CMake/Source/UtilityFooter.dsptemplate";
+      break;
     }
 
   // once the build type is set, determine what configurations are
@@ -400,7 +463,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout, const char *libName,
     {
     // add libraries to executables and dlls (but never include
     // a library in a library, bad recursion)
-    if (!target.IsALibrary() || 
+    if (!target.GetType() == cmTarget::LIBRARY || 
         (m_LibraryBuildType == DLL && libName != j->first))
       {
       if (j->second == cmTarget::GENERAL)

+ 2 - 1
Source/cmDSPWriter.h

@@ -57,7 +57,7 @@ public:
   cmDSPMakefile(cmMakefile*);
   ~cmDSPMakefile();
   void OutputDSPFile();
-  enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE};
+  enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE, UTILITY};
 
   /**
    * Specify the type of the build: static, dll, or executable.
@@ -107,6 +107,7 @@ private:
   void WriteDSPFooter(std::ostream& fout);
   void AddDSPBuildRule(cmSourceGroup&);
   void WriteCustomRule(std::ostream& fout,
+                       const char* source,
                        const char* command,
                        const std::set<std::string>& depends,
                        const std::set<std::string>& outputs);

+ 47 - 4
Source/cmDSWMakefile.cxx

@@ -91,8 +91,13 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
   // CMakeLists.txt files that are in sub directories of
   // this one.
   std::vector<cmMakefile*> allListFiles;
-  m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
+  // add this makefile to the list
+  allListFiles.push_back(m_Makefile);
+  // add a special target that depends on ALL projects for easy build
+  // of Debug only
+  m_Makefile->AddUtilityCommand("ALL_BUILD", "echo \"Build all projects\"");
   
+  m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
   // For each cmMakefile, create a DSP for it, and
   // add it to this DSW file
   for(std::vector<cmMakefile*>::iterator k = allListFiles.begin();
@@ -119,15 +124,52 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
     std::vector<std::string> dspnames = pg->GetDSPMakefile()->GetCreatedProjectNames();
     const cmTargets &tgts = pg->GetDSPMakefile()->GetMakefile()->GetTargets();
     cmTargets::const_iterator l = tgts.begin();
+    std::vector<std::string> originalUtilities;
+    bool addedUtilities = false;
     for(std::vector<std::string>::iterator si = dspnames.begin(); 
         l != tgts.end(); ++l, ++si)
       {
+      // special handling for the current makefile
+      if(mf == m_Makefile)
+        {
+        dir = "."; // no subdirectory for project generated
+        // if this is the special ALL_BUILD utility, then
+        // make it depend on every other non UTILITY project.
+        // This is done by adding the names to the GetUtilities
+        // vector on the makefile
+        if(l->first == "ALL_BUILD")
+          {
+          addedUtilities = true;
+          originalUtilities = m_Makefile->GetUtilities();
+          for(std::vector<cmMakefile*>::iterator a = allListFiles.begin();
+              a != allListFiles.end(); ++a)
+            {
+            const cmTargets &atgts = (*a)->GetTargets();
+            for(cmTargets::const_iterator al = atgts.begin();
+                al != atgts.end(); ++al)
+              {
+              if(al->second.GetType() != cmTarget::UTILITY)
+                {
+                m_Makefile->GetUtilities().push_back(al->first);
+                }
+              }
+            }
+          }
+        }
       // Write the project into the DSW file
       this->WriteProject(fout, si->c_str(), dir.c_str(), 
                          pg->GetDSPMakefile(),l->second);
+      if(addedUtilities)
+        {
+        m_Makefile->GetUtilities() = originalUtilities;
+        }
+      
       }
     // delete the cmMakefile which also deletes the cmMSProjectGenerator
-    delete mf;
+    if(mf != m_Makefile)
+      {
+      delete mf;
+      }
     }
   // Write the footer for the DSW file
   this->WriteDSWFooter(fout);
@@ -141,7 +183,8 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
 				 const char* dspname,
 				 const char* dir,
                                  cmDSPMakefile* project,
-                                 const cmTarget &l)
+                                 const cmTarget &l
+                                 )
 {
   fout << "#########################################################"
     "######################\n\n";
@@ -159,7 +202,7 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
     {
     if(j->first != dspname)
       {
-      if (!l.IsALibrary() || 
+      if (!(l.GetType() == cmTarget::LIBRARY) || 
           project->GetLibraryBuildType() == cmDSPMakefile::DLL)
         {
         // is the library part of this DSW ? If so add dependency

+ 0 - 2
Source/cmDSWMakefile.h

@@ -66,8 +66,6 @@ public:
   virtual void OutputDSWFile();
 
 private:
-  void FindAllCMakeListsFiles(const char* subdir,
-			      std::vector<cmMSProjectGenerator*>&);
   void WriteDSWFile(std::ostream& fout);
   void WriteDSWHeader(std::ostream& fout);
   void WriteProject(std::ostream& fout, 

+ 47 - 4
Source/cmDSWWriter.cxx

@@ -91,8 +91,13 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
   // CMakeLists.txt files that are in sub directories of
   // this one.
   std::vector<cmMakefile*> allListFiles;
-  m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
+  // add this makefile to the list
+  allListFiles.push_back(m_Makefile);
+  // add a special target that depends on ALL projects for easy build
+  // of Debug only
+  m_Makefile->AddUtilityCommand("ALL_BUILD", "echo \"Build all projects\"");
   
+  m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
   // For each cmMakefile, create a DSP for it, and
   // add it to this DSW file
   for(std::vector<cmMakefile*>::iterator k = allListFiles.begin();
@@ -119,15 +124,52 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
     std::vector<std::string> dspnames = pg->GetDSPMakefile()->GetCreatedProjectNames();
     const cmTargets &tgts = pg->GetDSPMakefile()->GetMakefile()->GetTargets();
     cmTargets::const_iterator l = tgts.begin();
+    std::vector<std::string> originalUtilities;
+    bool addedUtilities = false;
     for(std::vector<std::string>::iterator si = dspnames.begin(); 
         l != tgts.end(); ++l, ++si)
       {
+      // special handling for the current makefile
+      if(mf == m_Makefile)
+        {
+        dir = "."; // no subdirectory for project generated
+        // if this is the special ALL_BUILD utility, then
+        // make it depend on every other non UTILITY project.
+        // This is done by adding the names to the GetUtilities
+        // vector on the makefile
+        if(l->first == "ALL_BUILD")
+          {
+          addedUtilities = true;
+          originalUtilities = m_Makefile->GetUtilities();
+          for(std::vector<cmMakefile*>::iterator a = allListFiles.begin();
+              a != allListFiles.end(); ++a)
+            {
+            const cmTargets &atgts = (*a)->GetTargets();
+            for(cmTargets::const_iterator al = atgts.begin();
+                al != atgts.end(); ++al)
+              {
+              if(al->second.GetType() != cmTarget::UTILITY)
+                {
+                m_Makefile->GetUtilities().push_back(al->first);
+                }
+              }
+            }
+          }
+        }
       // Write the project into the DSW file
       this->WriteProject(fout, si->c_str(), dir.c_str(), 
                          pg->GetDSPMakefile(),l->second);
+      if(addedUtilities)
+        {
+        m_Makefile->GetUtilities() = originalUtilities;
+        }
+      
       }
     // delete the cmMakefile which also deletes the cmMSProjectGenerator
-    delete mf;
+    if(mf != m_Makefile)
+      {
+      delete mf;
+      }
     }
   // Write the footer for the DSW file
   this->WriteDSWFooter(fout);
@@ -141,7 +183,8 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
 				 const char* dspname,
 				 const char* dir,
                                  cmDSPMakefile* project,
-                                 const cmTarget &l)
+                                 const cmTarget &l
+                                 )
 {
   fout << "#########################################################"
     "######################\n\n";
@@ -159,7 +202,7 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
     {
     if(j->first != dspname)
       {
-      if (!l.IsALibrary() || 
+      if (!(l.GetType() == cmTarget::LIBRARY) || 
           project->GetLibraryBuildType() == cmDSPMakefile::DLL)
         {
         // is the library part of this DSW ? If so add dependency

+ 0 - 2
Source/cmDSWWriter.h

@@ -66,8 +66,6 @@ public:
   virtual void OutputDSWFile();
 
 private:
-  void FindAllCMakeListsFiles(const char* subdir,
-			      std::vector<cmMSProjectGenerator*>&);
   void WriteDSWFile(std::ostream& fout);
   void WriteDSWHeader(std::ostream& fout);
   void WriteProject(std::ostream& fout, 

+ 14 - 2
Source/cmMakefile.cxx

@@ -486,7 +486,7 @@ void cmMakefile::SetProjectName(const char* p)
 void cmMakefile::AddLibrary(const char* lname, const std::vector<std::string> &srcs)
 {
   cmTarget target;
-  target.SetIsALibrary(1);
+  target.SetType(cmTarget::LIBRARY);
   target.GetSourceLists() = srcs;
   m_Targets.insert(cmTargets::value_type(lname,target));
 }
@@ -495,12 +495,24 @@ void cmMakefile::AddExecutable(const char *exeName,
                                const std::vector<std::string> &srcs)
 {
   cmTarget target;
-  target.SetIsALibrary(0);
+  target.SetType(cmTarget::EXECUTABLE);
   target.GetSourceLists() = srcs;
   m_Targets.insert(cmTargets::value_type(exeName,target));
 }
 
 
+void cmMakefile::AddUtilityCommand(const char* utilityName,
+                                   const char* command)
+{
+  cmTarget target;
+  target.SetType(cmTarget::UTILITY);
+  std::vector<std::string> empty;
+  cmCustomCommand cc(utilityName, command, empty, empty);
+  target.GetCustomCommands().push_back(cc);
+  m_Targets.insert(cmTargets::value_type(utilityName,target));
+}
+
+
 void cmMakefile::AddSourceGroup(const char* name, const char* regex)
 {
   // First see if the group exists.  If so, replace its regular expression.

+ 11 - 0
Source/cmMakefile.h

@@ -95,6 +95,10 @@ public:
    * superclass.
    */
   void SetMakefileGenerator(cmMakefileGenerator*);
+  
+  ///! Get the current makefile generator.
+  cmMakefileGenerator* GetMakefileGenerator() 
+    { return m_MakefileGenerator;}
 
   /**
    * Produce the output makefile.
@@ -131,6 +135,13 @@ public:
    */
   void AddExecutable(const char *exename, const std::vector<std::string> &srcs);
 
+  /**
+   * Add a utility to the build.  A utiltity target is
+   * a command that is run every time a target is built.
+   */
+  void AddUtilityCommand(const char* utilityName,
+                         const char* command);
+
   /**
    * Add a utility on which this project depends. A utility is an executable
    * name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE

+ 9 - 5
Source/cmTarget.h

@@ -54,12 +54,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 class cmTarget
 {
 public:
+  enum TargetType { EXECUTABLE, LIBRARY, UTILITY };
   /**
-   * is this target a library?
+   * Return the type of target.
    */
-  bool IsALibrary() const { return m_IsALibrary; }
-  bool GetIsALibrary() const { return m_IsALibrary; }
-  void SetIsALibrary(bool f) { m_IsALibrary = f; }
+  TargetType GetType() const
+    {
+      return m_TargetType;
+    }
+  
+  void SetType(TargetType f) { m_TargetType = f; }
   
   /**
    * Get the list of the custom commands for this target
@@ -103,7 +107,7 @@ public:
 private:
   std::vector<cmCustomCommand> m_CustomCommands;
   std::vector<std::string> m_SourceLists;
-  bool m_IsALibrary;
+  TargetType m_TargetType;
   std::vector<cmSourceFile> m_SourceFiles;
   LinkLibraries m_LinkLibraries;
 };

+ 10 - 4
Source/cmUnixMakefileGenerator.cxx

@@ -99,7 +99,7 @@ void cmUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
   for(cmTargets::const_iterator l = tgts.begin(); 
       l != tgts.end(); l++)
     {
-    if (l->second.IsALibrary())
+    if (l->second.GetType() == cmTarget::LIBRARY)
       {
       fout << " \\\nlib" << l->first.c_str() << "${CMAKE_LIB_EXT}";
       }
@@ -108,7 +108,7 @@ void cmUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
   for(cmTargets::const_iterator l = tgts.begin(); 
       l != tgts.end(); l++)
     {
-    if (!l->second.IsALibrary())
+    if (!l->second.GetType() == cmTarget::LIBRARY)
       {
       fout << "\\\n" << l->first.c_str();
       }
@@ -195,7 +195,7 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
   for(cmTargets::const_iterator l = tgts.begin(); 
       l != tgts.end(); l++)
     {
-    if (l->second.IsALibrary())
+    if (l->second.GetType() == cmTarget::LIBRARY)
       {
       fout << "#---------------------------------------------------------\n";
       fout << "# rules for a library\n";
@@ -217,7 +217,7 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
       this->OutputLinkLibraries(fout, l->first.c_str(), l->second);
       fout << "\n\n";
       }
-    else
+    else if (l->second.GetType() == cmTarget::EXECUTABLE)
       {
       fout << l->first << ": ${" << 
         l->first << "_SRC_OBJS} ${CMAKE_DEPEND_LIBS}\n";
@@ -487,6 +487,12 @@ void cmUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
         {
         std::string command = c->first;
         const cmSourceGroup::CommandFiles& commandFiles = c->second;
+        // if the command has no outputs, then it is a utility command
+        // with no outputs or depends
+        if(commandFiles.m_Outputs.size() == 0)
+          {
+          fout << source.c_str() << ":\n\t" << command.c_str() << "\n\n";
+          }
         // Write a rule for every output generated by this command.
         for(std::set<std::string>::const_iterator output =
               commandFiles.m_Outputs.begin();

+ 36 - 54
configure.in.sample

@@ -1,8 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 AC_INIT()
 
-AC_CONFIG_HEADER(CMake/Source/cmConfigure.h)
-
 CMAKE_CONFIG_DIR=`pwd`
 AC_SUBST(CMAKE_CONFIG_DIR)
 
@@ -187,7 +185,10 @@ case $system in
 	fi
 	;;
     CYGWIN_NT*)
-        DL_LIBS="-lgdi32"
+        SHLIB_CFLAGS=""
+        DL_LIBS="-lgdi32" 
+        SHLIB_SUFFIX=".dll"
+        CMAKE_SHLIB_LINK_FLAGS="-shared"
         ;;
     MP-RAS-02*)
 	SHLIB_CFLAGS="-K PIC"
@@ -319,6 +320,12 @@ export SHLIB_SUFFIX
 if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
   SHLIB_CFLAGS="-fPIC"
 fi
+# if running on cygwin remove -fPIC flag
+case $system in 
+  CYGWIN_NT*)
+    SHLIB_CFLAGS=""
+    ;;
+esac
 
 if test "$CMAKE_shared_ok" = "yes"; then
     CMAKE_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
@@ -563,59 +570,38 @@ fi
 
 AC_SUBST(EXTRA_GCC_FLAG)
 
-AC_CONFIG_SUBDIRS(Code/Numerics/vxl)
-AC_CONFIG_SUBDIRS(Code/Numerics/vxl/vcl)
-
-# *****************************************
-# 
-#  This next section extracts the sub-directories from 
-#  the CMakeLists.txt file in the current directory,
-#  and any sub directories recursivley 
-#
-
-#
-# Build two variables (SITE, INSTANCE) used for setting up testing
-#
-
-AC_ARG_WITH(site,
-         [  --with-site             sitename used for testing],
-         [site_specified=$withval], [site_specified=none])
-
-AC_ARG_WITH(buildname,
-         [  --with-buildname        name of build used for testing],
-         [buildname_specified=$withval], [buildname_specified=none])
-
-# Determine the site (domain) name
-AC_PATH_PROG(HOSTNAME, hostname, hostname, $PATH:/usr/bsd:/usr/sbin:/usr/bin:/bin:/sbin)
-AC_PATH_PROG(NSLOOKUP, nslookup, nslookup, $PATH:/usr/bin:/usr/sbin:/usr/local/bin)
-# Fallback site
-myhostname=`$HOSTNAME`
-SITE=`$NSLOOKUP $myhostname | grep \^Name: | cut -d. -f2- | tr [A-Z] [a-z]`
-if test ! "$site_specified" = none; then
-	SITE=$site_specified
-fi
-if test -z "$SITE"; then
-	SITE=nosite
-fi
-AC_SUBST(SITE)
-
-# Setup the instance name (OS, Revision, Compiler, and someday Compiler Revision)
-COMPILER=`echo $CXX | cut -d ' ' -f1`
-COMPILER=`basename $COMPILER`
-BUILDNAME=$system-$COMPILER
-BUILDNAME=`echo $BUILDNAME | tr [\(\/] _ | tr -d \)`
-if test ! "$buildname_specified" = none; then
-	BUILDNAME=$buildname_specified
-fi
-AC_SUBST(BUILDNAME)
 
 
 # output to the top level Makefile, which must be present
 # create the toplevel CMakeTargets.make file
 # Create all the make file fragments in CMake
 # Create the Makefile in CMake/Source
-# Create all the Makefiles and CMakeTargets.make files for
-# sub directories found in CMakeLists.txt files
+
+# Testing system configuration
+AC_PATH_PROGS(MAKECOMMAND, gmake make)
+AC_PATH_PROGS(CVSCOMMAND, cvs )
+AC_PATH_PROGS(GREPCOMMAND, grep )
+AC_PATH_PROGS(COMPRESSIONCOMMAND, gzip compress zip )
+AC_PATH_PROGS(TCLSHCOMMAND, cygtclsh80 tclsh tclsh82 tclsh8.2 tclsh80 tclsh8.2 )
+AC_PATH_PROGS(GUNZIPCOMMAND, gunzip )
+
+AC_SUBST(MAKECOMMAND)
+AC_SUBST(CVSCOMMAND)
+AC_SUBST(GREPCOMMAND)
+AC_SUBST(GUNZIPCOMMAND)
+AC_SUBST(COMPRESSIONCOMMAND)
+AC_SUBST(TCLSHCOMMAND)
+
+# Make java optional
+AC_PATH_PROGS(JAVACOMMAND, java, jre )
+AC_SUBST(JAVACOMMAND)
+
+# AC_PROG_JAVA
+# AC_PROG_JAVAC
+# AC_PROG_JAR
+
+# generate output files.
+# create mkdir files just to make some of the directories
 
 AC_OUTPUT(
 Makefile:CMake/CMakeTopMakefileTemplate.in
@@ -629,10 +615,6 @@ CMake/Source/Makefile
 )
 
 
-
-
-
-
 # build the CMakeBuildTargets program
 (cd CMake/Source; $MAKECOMMAND CMakeBuildTargets)
 # if there is no cache file then create one