Selaa lähdekoodia

some cleanup and fixes

Ken Martin 25 vuotta sitten
vanhempi
sitoutus
fce56c57c4

+ 1 - 1
CMakeRules.make.in

@@ -21,7 +21,7 @@ clean: ${SUBDIR_CLEAN}
 	rm -f ${SRC_OBJ} ${EXECUTABLES} 
 
 CMakeTargets.make: ${CMAKE} ${srcdir}/CMakeLists.txt
-	${CMAKE} ${srcdir}/CMakeLists.txt -S${currentdir} -H${topdir} -B${CMAKE_CONFIG_DIR}
+	${CMAKE} ${srcdir}/CMakeLists.txt -S${currentdir} -O${currentbindir} -H${topdir} -B${CMAKE_CONFIG_DIR}
 
 #------------------------------------------------------------------------------
 # rules for the normal library

+ 3 - 0
CMakeVariables.make.in

@@ -34,6 +34,9 @@ topdir = @fullSrcDir@
 # This is the directory that contains the source for the CMakeLists.txt file
 currentdir = `cd ${srcdir}; pwd`
 
+# This is the directory that contains the output for the CMakeLists.txt file
+currentbindir = `pwd`
+
 # This is the directory configure was run in
 # where the binaries will be placed
 CMAKE_CONFIG_DIR = @CMAKE_CONFIG_DIR@

+ 13 - 7
Source/CMakeBuildTargets.cxx

@@ -36,18 +36,17 @@ int main(int ac, char** av)
     for(int i =2; i < ac; i++)
       {
       std::string arg = av[i];
-      // Set the current source directory with a -S dir options
+      // Set the start source directory with a -S dir options
       if(arg.find("-S",0) == 0)
 	{
 	std::string path = arg.substr(2);
-	mf.SetCurrentDirectory(path.c_str());
+	mf.SetStartDirectory(path.c_str());
 	}
-      // Set the output or binary directory with a -B dir option
-      if(arg.find("-B",0) == 0)
+      // Set the start output directory with a -O dir options
+      if(arg.find("-O",0) == 0)
 	{
 	std::string path = arg.substr(2);
-	mf.SetOutputHomeDirectory(path.c_str());
-	mf.SetOutputDirectory(path.c_str());
+	mf.SetStartOutputDirectory(path.c_str());
 	}
       // Set the source home directory with a -H dir option
       if(arg.find("-H",0) == 0)
@@ -55,12 +54,19 @@ int main(int ac, char** av)
 	std::string path = arg.substr(2);
 	mf.SetHomeDirectory(path.c_str());
 	}
+      // Set the output or binary directory with a -B dir option
+      if(arg.find("-B",0) == 0)
+	{
+	std::string path = arg.substr(2);
+	mf.SetHomeOutputDirectory(path.c_str());
+	}
       }
     }
   mf.SetMakefileGenerator(new cmUnixMakefileGenerator);
 
   // Read and parse the input makefile
-  if(!mf.ReadMakefile(av[1]))
+  mf.MakeStartDirectoriesCurrent();
+  if(!mf.ReadListFile(av[1]))
     {
     std::cerr << "Usage: " << av[0] << " Makefile.in  -Ipath ..." << std::endl;
     return -1;

+ 6 - 5
Source/CMakeSetupCMD.cxx

@@ -34,20 +34,20 @@ void SetArgs(cmMakefile& builder, int ac, char** av)
       std::string path = arg.substr(2);
       builder.SetHomeDirectory(path.c_str());
       }
-    if(arg.find("-D",0) != std::string::npos)
+    if(arg.find("-S",0) != std::string::npos)
       {
       std::string path = arg.substr(2);
-      builder.SetCurrentDirectory(path.c_str());
+      builder.SetStartDirectory(path.c_str());
       }
     if(arg.find("-O",0) != std::string::npos)
       {
       std::string path = arg.substr(2);
-      builder.SetOutputDirectory(path.c_str());
+      builder.SetStartOutputDirectory(path.c_str());
       }
     if(arg.find("-B",0) != std::string::npos)
       {
       std::string path = arg.substr(2);
-      builder.SetOutputHomeDirectory(path.c_str());
+      builder.SetHomeOutputDirectory(path.c_str());
       std::cout << "set output home to " << path.c_str() << std::endl;
       }
     }
@@ -76,7 +76,8 @@ int main(int ac, char** av)
     pg->BuildDSWOn();
     }
   builder.SetMakefileGenerator(pg);
-  builder.ReadMakefile(av[1]);
+  builder.MakeStartDirectoriesCurrent();
+  builder.ReadListFile(av[1]);
   builder.GenerateMakefile();
   return 0;
 }

+ 5 - 4
Source/MFCDialog/CMakeSetupDialog.cpp

@@ -257,15 +257,16 @@ void CMakeSetupDialog::OnOK()
   mf.SetHomeDirectory(m_WhereSource);
 
   // Set the output directory
-  mf.SetOutputDirectory(m_WhereBuild);
-  mf.SetOutputHomeDirectory(m_WhereBuild);
+  mf.SetStartOutputDirectory(m_WhereBuild);
+  mf.SetHomeOutputDirectory(m_WhereBuild);
   // set the directory which contains the CMakeLists.txt
-  mf.SetCurrentDirectory(m_WhereSource);
+  mf.SetStartDirectory(m_WhereSource);
   // Create the master DSW file and all children dsp files for ITK
   // Set the CMakeLists.txt file
   CString makefileIn = m_WhereSource;
   makefileIn += "/CMakeLists.txt";
-  mf.ReadMakefile(makefileIn);
+  mf.MakeStartDirectoriesCurrent();
+  mf.ReadListFile(makefileIn);
   // Move this to the cache editor
   mf.GenerateMakefile();
   CDialog::OnOK();

+ 4 - 0
Source/cmClassFile.cxx

@@ -90,5 +90,9 @@ void cmClassFile::Print()
     std::cout << "Header file ";
   else
     std::cout << "CXX file ";
+  if(m_IsExecutable)
+    std::cout << "Executable ";
+  else
+    std::cout << "Non Executable ";
   std::cout << m_ClassName << std::endl;
 }

+ 6 - 0
Source/cmClassFile.h

@@ -35,6 +35,7 @@ public:
     {
     m_AbstractClass = false;
     m_HeaderFileOnly = false;
+    m_IsExecutable = false;
     }
   
   /**
@@ -59,6 +60,11 @@ public:
    */
   bool m_HeaderFileOnly;
 
+  /**
+   * Indicate whether this class is an executable file
+   */
+  bool m_IsExecutable;
+
   /**
    * The full path to the file.
    */

+ 2 - 1
Source/cmConfigureFileNoAutoconf.h

@@ -55,7 +55,8 @@ public:
         "CONFIGURE_HEADER(InputFile OutputFile)\n"
 	"The Input and Ouput files have to have full paths.\n"
 	"They can also use variables like CMAKE_BINARY_DIR,CMAKE_SOURCE_DIR.\n"
-        "This command is only run if autoconf was not used.\n";
+        "This command is only run if configure was not used. In other\n";
+        "words it is only run for non UNIX style builds.\n";
     }
 
   /**

+ 41 - 41
Source/cmDSPMakefile.cxx

@@ -79,28 +79,25 @@ void cmDSPMakefile::OutputDSPFile()
   cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
   // If the output directory is not the m_cmHomeDirectory
   // then create it.
-  if(strcmp(m_Makefile->GetOutputDirectory(),
+  if(strcmp(m_Makefile->GetStartOutputDirectory(),
             m_Makefile->GetHomeDirectory()) != 0)
     {
-    if(!cmSystemTools::MakeDirectory(m_Makefile->GetOutputDirectory()))
+    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
       {
       std::string message = "Error creating directory ";
-      message += m_Makefile->GetOutputDirectory();
+      message += m_Makefile->GetStartOutputDirectory();
       Die(message.c_str());
       }
     }
   
-  if(!m_Makefile->HasExecutables())
+  // if there is a library, build it
+  if(strlen(m_Makefile->GetLibraryName()) != 0)
     {
-    if(strlen(m_Makefile->GetLibraryName()) == 0)
-      {
-      // if no library silently give up
-      return;
-      }
     this->SetBuildType(STATIC_LIBRARY);
     this->CreateSingleDSP();
     }
-  else
+  // if there are executables build them
+  if (m_Makefile->HasExecutables())
     {
     this->CreateExecutableDSPFiles();
     }
@@ -111,32 +108,34 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
   for(int i = 0; i < Classes.size(); ++i)
     {
     cmClassFile& classfile = Classes[i];
-    std::string fname = m_Makefile->GetOutputDirectory();
-    fname += "/";
-    fname += classfile.m_ClassName;
-    fname += ".dsp";
-    std::ofstream fout(fname.c_str());
-    if(!fout)
-      {
-      std::string message = "Error Writing ";
-      message += fname;
-      Die(message.c_str());
-      }
-    else
+    if (classfile.m_IsExecutable)
       {
-      m_Makefile->SetLibraryName(classfile.m_ClassName.c_str());
-      this->SetBuildType(EXECUTABLE);
-      std::string pname = m_Makefile->GetLibraryName();
-      m_CreatedProjectNames.push_back(pname);
-
-      this->WriteDSPHeader(fout);
-      this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
-      this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
-      this->WriteDSPEndGroup(fout);
-      this->WriteDSPBuildRule(fout);
-      this->WriteDSPFooter(fout);
+      std::string fname = m_Makefile->GetStartOutputDirectory();
+      fname += "/";
+      fname += classfile.m_ClassName;
+      fname += ".dsp";
+      std::ofstream fout(fname.c_str());
+      if(!fout)
+        {
+        std::string message = "Error Writing ";
+        message += fname;
+        Die(message.c_str());
+        }
+      else
+        {
+        m_Makefile->SetLibraryName(classfile.m_ClassName.c_str());
+        this->SetBuildType(EXECUTABLE);
+        std::string pname = m_Makefile->GetLibraryName();
+        m_CreatedProjectNames.push_back(pname);
+        
+        this->WriteDSPHeader(fout);
+        this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+        this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
+        this->WriteDSPEndGroup(fout);
+        this->WriteDSPBuildRule(fout);
+        this->WriteDSPFooter(fout);
+        }
       }
-    
     }
 }
 
@@ -144,7 +143,7 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
 void cmDSPMakefile::CreateSingleDSP()
 {
   std::string fname;
-  fname = m_Makefile->GetOutputDirectory();
+  fname = m_Makefile->GetStartOutputDirectory();
   fname += "/";
   fname += m_Makefile->GetLibraryName();
   fname += ".dsp";
@@ -165,7 +164,7 @@ void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
 {
   std::string dspname = *(m_CreatedProjectNames.end()-1);
   dspname += ".dsp";
-  std::string makefileIn = m_Makefile->GetCurrentDirectory();
+  std::string makefileIn = m_Makefile->GetStartDirectory();
   makefileIn += "/";
   makefileIn += "CMakeLists.txt";
   std::string dsprule = m_Makefile->GetHomeDirectory();
@@ -173,12 +172,12 @@ void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
   dsprule += makefileIn;
   dsprule += " -DSP -H";
   dsprule += m_Makefile->GetHomeDirectory();
-  dsprule += " -D";
-  dsprule += m_Makefile->GetCurrentDirectory();
+  dsprule += " -S";
+  dsprule += m_Makefile->GetStartDirectory();
   dsprule += " -O";
-  dsprule += m_Makefile->GetOutputDirectory();
+  dsprule += m_Makefile->GetStartOutputDirectory();
   dsprule += " -B";
-  dsprule += m_Makefile->GetOutputHomeDirectory();
+  dsprule += m_Makefile->GetHomeOutputDirectory();
   this->WriteCustomRule(fout, makefileIn.c_str(), 
 			dspname.c_str(),
 			dsprule.c_str());
@@ -307,7 +306,8 @@ void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout)
   std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
   for(int i = 0; i < Classes.size(); ++i)
     {
-    if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly)
+    if(!Classes[i].m_IsExecutable && !Classes[i].m_AbstractClass && 
+       !Classes[i].m_HeaderFileOnly)
       {
       this->WriteDSPBuildRule(fout, Classes[i].m_FullPath.c_str());
       }

+ 41 - 41
Source/cmDSPWriter.cxx

@@ -79,28 +79,25 @@ void cmDSPMakefile::OutputDSPFile()
   cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
   // If the output directory is not the m_cmHomeDirectory
   // then create it.
-  if(strcmp(m_Makefile->GetOutputDirectory(),
+  if(strcmp(m_Makefile->GetStartOutputDirectory(),
             m_Makefile->GetHomeDirectory()) != 0)
     {
-    if(!cmSystemTools::MakeDirectory(m_Makefile->GetOutputDirectory()))
+    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
       {
       std::string message = "Error creating directory ";
-      message += m_Makefile->GetOutputDirectory();
+      message += m_Makefile->GetStartOutputDirectory();
       Die(message.c_str());
       }
     }
   
-  if(!m_Makefile->HasExecutables())
+  // if there is a library, build it
+  if(strlen(m_Makefile->GetLibraryName()) != 0)
     {
-    if(strlen(m_Makefile->GetLibraryName()) == 0)
-      {
-      // if no library silently give up
-      return;
-      }
     this->SetBuildType(STATIC_LIBRARY);
     this->CreateSingleDSP();
     }
-  else
+  // if there are executables build them
+  if (m_Makefile->HasExecutables())
     {
     this->CreateExecutableDSPFiles();
     }
@@ -111,32 +108,34 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
   for(int i = 0; i < Classes.size(); ++i)
     {
     cmClassFile& classfile = Classes[i];
-    std::string fname = m_Makefile->GetOutputDirectory();
-    fname += "/";
-    fname += classfile.m_ClassName;
-    fname += ".dsp";
-    std::ofstream fout(fname.c_str());
-    if(!fout)
-      {
-      std::string message = "Error Writing ";
-      message += fname;
-      Die(message.c_str());
-      }
-    else
+    if (classfile.m_IsExecutable)
       {
-      m_Makefile->SetLibraryName(classfile.m_ClassName.c_str());
-      this->SetBuildType(EXECUTABLE);
-      std::string pname = m_Makefile->GetLibraryName();
-      m_CreatedProjectNames.push_back(pname);
-
-      this->WriteDSPHeader(fout);
-      this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
-      this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
-      this->WriteDSPEndGroup(fout);
-      this->WriteDSPBuildRule(fout);
-      this->WriteDSPFooter(fout);
+      std::string fname = m_Makefile->GetStartOutputDirectory();
+      fname += "/";
+      fname += classfile.m_ClassName;
+      fname += ".dsp";
+      std::ofstream fout(fname.c_str());
+      if(!fout)
+        {
+        std::string message = "Error Writing ";
+        message += fname;
+        Die(message.c_str());
+        }
+      else
+        {
+        m_Makefile->SetLibraryName(classfile.m_ClassName.c_str());
+        this->SetBuildType(EXECUTABLE);
+        std::string pname = m_Makefile->GetLibraryName();
+        m_CreatedProjectNames.push_back(pname);
+        
+        this->WriteDSPHeader(fout);
+        this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+        this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
+        this->WriteDSPEndGroup(fout);
+        this->WriteDSPBuildRule(fout);
+        this->WriteDSPFooter(fout);
+        }
       }
-    
     }
 }
 
@@ -144,7 +143,7 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
 void cmDSPMakefile::CreateSingleDSP()
 {
   std::string fname;
-  fname = m_Makefile->GetOutputDirectory();
+  fname = m_Makefile->GetStartOutputDirectory();
   fname += "/";
   fname += m_Makefile->GetLibraryName();
   fname += ".dsp";
@@ -165,7 +164,7 @@ void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
 {
   std::string dspname = *(m_CreatedProjectNames.end()-1);
   dspname += ".dsp";
-  std::string makefileIn = m_Makefile->GetCurrentDirectory();
+  std::string makefileIn = m_Makefile->GetStartDirectory();
   makefileIn += "/";
   makefileIn += "CMakeLists.txt";
   std::string dsprule = m_Makefile->GetHomeDirectory();
@@ -173,12 +172,12 @@ void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
   dsprule += makefileIn;
   dsprule += " -DSP -H";
   dsprule += m_Makefile->GetHomeDirectory();
-  dsprule += " -D";
-  dsprule += m_Makefile->GetCurrentDirectory();
+  dsprule += " -S";
+  dsprule += m_Makefile->GetStartDirectory();
   dsprule += " -O";
-  dsprule += m_Makefile->GetOutputDirectory();
+  dsprule += m_Makefile->GetStartOutputDirectory();
   dsprule += " -B";
-  dsprule += m_Makefile->GetOutputHomeDirectory();
+  dsprule += m_Makefile->GetHomeOutputDirectory();
   this->WriteCustomRule(fout, makefileIn.c_str(), 
 			dspname.c_str(),
 			dsprule.c_str());
@@ -307,7 +306,8 @@ void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout)
   std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
   for(int i = 0; i < Classes.size(); ++i)
     {
-    if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly)
+    if(!Classes[i].m_IsExecutable && !Classes[i].m_AbstractClass && 
+       !Classes[i].m_HeaderFileOnly)
       {
       this->WriteDSPBuildRule(fout, Classes[i].m_FullPath.c_str());
       }

+ 16 - 15
Source/cmDSWMakefile.cxx

@@ -32,24 +32,24 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
 // output the DSW file
 void cmDSWMakefile::OutputDSWFile()
 { 
-  if(m_Makefile->GetOutputDirectory() == "")
+  if(m_Makefile->GetStartOutputDirectory() == "")
     {
     // default to build in place
-    m_Makefile->SetOutputDirectory(m_Makefile->GetHomeDirectory());
+    m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
     }
   // If the output directory is not the m_cmHomeDirectory
   // then create it.
-  if(strcmp(m_Makefile->GetOutputDirectory(),
+  if(strcmp(m_Makefile->GetStartOutputDirectory(),
             m_Makefile->GetHomeDirectory()) != 0)
     {
-    if(!cmSystemTools::MakeDirectory(m_Makefile->GetOutputDirectory()))
+    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
       {
       MessageBox(0, "Error creating directory ", 0, MB_OK);
-      MessageBox(0, m_Makefile->GetOutputDirectory(), 0, MB_OK);
+      MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK);
       }
     }
   std::string fname;
-  fname = m_Makefile->GetOutputDirectory();
+  fname = m_Makefile->GetStartOutputDirectory();
   fname += "/";
   fname += m_Makefile->GetProjectName();
   fname += ".dsw";
@@ -91,22 +91,23 @@ cmDSWMakefile
     // add it to the vector
     makefiles.push_back(pg);
     // Set up the file with the current context
-    mf->SetOutputHomeDirectory(m_Makefile->GetOutputDirectory());
+    mf->SetHomeOutputDirectory(m_Makefile->GetStartOutputDirectory());
     mf->SetHomeDirectory(m_Makefile->GetHomeDirectory());
+    // Set the output directory which may be different than the source
+    std::string outdir = m_Makefile->GetStartOutputDirectory();
+    outdir += "/";
+    outdir += subdir;
+    mf->SetStartOutputDirectory(outdir.c_str());
     // set the current directory in the Source as a full
     // path
-    std::string currentDir = m_Makefile->GetCurrentDirectory();
+    std::string currentDir = m_Makefile->GetStartDirectory();
     currentDir += "/";
     currentDir += subdir;
-    mf->SetCurrentDirectory(currentDir.c_str());
+    mf->SetStartDirectory(currentDir.c_str());
     // Parse the CMakeLists.txt file
     currentDir += "/CMakeLists.txt";
-    mf->ReadMakefile(currentDir.c_str());
-    // Set the output directory which may be different than the source
-    std::string outdir = m_Makefile->GetOutputDirectory();
-    outdir += "/";
-    outdir += subdir;
-    mf->SetOutputDirectory(outdir.c_str());
+    mf->MakeStartDirectoriesCurrent();
+    mf->ReadListFile(currentDir.c_str());
     // Create the DSP file
     mf->GenerateMakefile();
     // Look at any sub directories parsed (SUBDIRS) and 

+ 16 - 15
Source/cmDSWWriter.cxx

@@ -32,24 +32,24 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
 // output the DSW file
 void cmDSWMakefile::OutputDSWFile()
 { 
-  if(m_Makefile->GetOutputDirectory() == "")
+  if(m_Makefile->GetStartOutputDirectory() == "")
     {
     // default to build in place
-    m_Makefile->SetOutputDirectory(m_Makefile->GetHomeDirectory());
+    m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
     }
   // If the output directory is not the m_cmHomeDirectory
   // then create it.
-  if(strcmp(m_Makefile->GetOutputDirectory(),
+  if(strcmp(m_Makefile->GetStartOutputDirectory(),
             m_Makefile->GetHomeDirectory()) != 0)
     {
-    if(!cmSystemTools::MakeDirectory(m_Makefile->GetOutputDirectory()))
+    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
       {
       MessageBox(0, "Error creating directory ", 0, MB_OK);
-      MessageBox(0, m_Makefile->GetOutputDirectory(), 0, MB_OK);
+      MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK);
       }
     }
   std::string fname;
-  fname = m_Makefile->GetOutputDirectory();
+  fname = m_Makefile->GetStartOutputDirectory();
   fname += "/";
   fname += m_Makefile->GetProjectName();
   fname += ".dsw";
@@ -91,22 +91,23 @@ cmDSWMakefile
     // add it to the vector
     makefiles.push_back(pg);
     // Set up the file with the current context
-    mf->SetOutputHomeDirectory(m_Makefile->GetOutputDirectory());
+    mf->SetHomeOutputDirectory(m_Makefile->GetStartOutputDirectory());
     mf->SetHomeDirectory(m_Makefile->GetHomeDirectory());
+    // Set the output directory which may be different than the source
+    std::string outdir = m_Makefile->GetStartOutputDirectory();
+    outdir += "/";
+    outdir += subdir;
+    mf->SetStartOutputDirectory(outdir.c_str());
     // set the current directory in the Source as a full
     // path
-    std::string currentDir = m_Makefile->GetCurrentDirectory();
+    std::string currentDir = m_Makefile->GetStartDirectory();
     currentDir += "/";
     currentDir += subdir;
-    mf->SetCurrentDirectory(currentDir.c_str());
+    mf->SetStartDirectory(currentDir.c_str());
     // Parse the CMakeLists.txt file
     currentDir += "/CMakeLists.txt";
-    mf->ReadMakefile(currentDir.c_str());
-    // Set the output directory which may be different than the source
-    std::string outdir = m_Makefile->GetOutputDirectory();
-    outdir += "/";
-    outdir += subdir;
-    mf->SetOutputDirectory(outdir.c_str());
+    mf->MakeStartDirectoriesCurrent();
+    mf->ReadListFile(currentDir.c_str());
     // Create the DSP file
     mf->GenerateMakefile();
     // Look at any sub directories parsed (SUBDIRS) and 

+ 88 - 39
Source/cmMakefile.cxx

@@ -26,7 +26,6 @@
 cmMakefile::cmMakefile()
 {
   m_DefineFlags = " ";
-  m_Executables = false;
   m_MakefileGenerator = 0;
   this->AddDefaultCommands();
 }
@@ -84,14 +83,18 @@ void cmMakefile::Print()
   std::cout << "classes:\n";
   for(unsigned int i = 0; i < m_Classes.size(); i++)
     m_Classes[i].Print();
-  std::cout << " m_OutputDirectory; " << 
-    m_OutputDirectory.c_str() << std::endl;
-  std::cout << " m_OutputHomeDirectory; " << 
-    m_OutputHomeDirectory.c_str() << std::endl;
-  std::cout << " m_cmHomeDirectory; " << 
-    m_cmHomeDirectory.c_str() << std::endl;
+  std::cout << " m_CurrentOutputDirectory; " << 
+    m_CurrentOutputDirectory.c_str() << std::endl;
+  std::cout << " m_StartOutputDirectory; " << 
+    m_StartOutputDirectory.c_str() << std::endl;
+  std::cout << " m_HomeOutputDirectory; " << 
+    m_HomeOutputDirectory.c_str() << std::endl;
   std::cout << " m_cmCurrentDirectory; " << 
     m_cmCurrentDirectory.c_str() << std::endl;
+  std::cout << " m_cmStartDirectory; " << 
+    m_cmStartDirectory.c_str() << std::endl;
+  std::cout << " m_cmHomeDirectory; " << 
+    m_cmHomeDirectory.c_str() << std::endl;
   std::cout << " m_LibraryName;	" <<  m_LibraryName.c_str() << std::endl;
   std::cout << " m_ProjectName;	" <<  m_ProjectName.c_str() << std::endl;
   this->PrintStringVector("m_SubDirectories ", m_SubDirectories); 
@@ -104,22 +107,39 @@ void cmMakefile::Print()
 }
 
 // Parse the given CMakeLists.txt file into a list of classes.
-bool cmMakefile::ReadMakefile(const char* filename, bool inheriting)
+// Reads in current CMakeLists file and all parent CMakeLists files
+// executing all inherited commands in the parents
+bool cmMakefile::ReadListFile(const char* filename)
 {
-  // If not being called from ParseDirectory which
-  // sets the inheriting flag, then parse up the
-  // tree and collect inherited parameters
-  if(!inheriting)
+  // is there a parent CMakeLists file that does not go beyond the
+  // Home directory? if so recurse and read in that List file 
+  std::string parentList = this->GetParentListFileName(filename);
+  if (parentList != "")
     {
-    cmSystemTools::ConvertToUnixSlashes(m_cmCurrentDirectory);
-    m_SourceHomeDirectory = m_cmHomeDirectory;
-    cmSystemTools::ConvertToUnixSlashes(m_SourceHomeDirectory);
-    // if this is already the top level directory then 
-    if(m_SourceHomeDirectory != m_cmCurrentDirectory)
+    // save the current directory
+    std::string srcdir = m_cmCurrentDirectory;
+    std::string bindir = m_CurrentOutputDirectory;    
+    // compute the new current directories
+    std::string::size_type pos = m_cmCurrentDirectory.rfind('/');
+    if(pos != std::string::npos)
+      {
+      m_cmCurrentDirectory = m_cmCurrentDirectory.substr(0, pos);
+      }
+    pos = m_CurrentOutputDirectory.rfind('/');
+    if(pos != std::string::npos)
       {
-      this->ParseDirectory(m_cmCurrentDirectory.c_str());
+      m_CurrentOutputDirectory = m_CurrentOutputDirectory.substr(0, pos);
       }
+    this->ReadListFile(parentList.c_str());
+    // restore the current directory
+    m_cmCurrentDirectory = srcdir;
+    m_CurrentOutputDirectory = bindir;    
     }
+
+  // are we at the start CMakeLists file or are we processing a parent 
+  // lists file
+  bool inheriting = (m_cmCurrentDirectory != m_cmStartDirectory);
+                    
   // Now read the input file
   std::ifstream fin(filename);
   if(!fin)
@@ -137,7 +157,7 @@ bool cmMakefile::ReadMakefile(const char* filename, bool inheriting)
       // ADD_COMMAND is implemented
       if(name == "VERBATIM")
         {
-        if(!inheriting)
+        if (!inheriting)
           {
           m_MakeVerbatim = arguments;
           }
@@ -248,8 +268,20 @@ void cmMakefile::AddDefineFlag(const char* flag)
 
 void cmMakefile::AddExecutable(cmClassFile& cf)
 {
+  cf.m_IsExecutable = true;
   m_Classes.push_back(cf);
-  m_Executables = true;
+}
+
+bool cmMakefile::HasExecutables()
+{
+  for(unsigned int i = 0; i < m_Classes.size(); i++)
+    {
+    if (m_Classes[i].m_IsExecutable)
+      {
+      return true;
+      }
+    }
+  return false;
 }
 
 void cmMakefile::AddLinkLibrary(const char* lib)
@@ -294,40 +326,57 @@ void cmMakefile::AddExtraDirectory(const char* dir)
 }
 
 
-// Go until directory == m_cmHomeDirectory 
-// 1. fix slashes
-// 2. peal off /dir until home found, go no higher
-void cmMakefile::ParseDirectory(const char* dir)
+// return the file name for the parent CMakeLists file to the 
+// one passed in. Zero is returned if the CMakeLists file is the
+// one in the home directory or if for some reason a parent cmake lists 
+// file cannot be found.
+std::string cmMakefile::GetParentListFileName(const char *currentFileName)
 {
-  std::string listsFile = dir;
-  listsFile += "/CMakeLists.txt";
-  if(cmSystemTools::FileExists(listsFile.c_str()))
+  // extract the directory name
+  std::string parentFile;
+  std::string listsDir = currentFileName;
+  std::string::size_type pos = listsDir.rfind('/');
+  // if we could not find the directory return 0
+  if(pos == std::string::npos)
     {
-    this->ReadMakefile(listsFile.c_str(), true);
+    return parentFile;
     }
-  if(m_SourceHomeDirectory == dir)
+  listsDir = listsDir.substr(0, pos);
+  
+  // if we are in the home directory then stop, return 0
+  if(m_cmHomeDirectory == listsDir)
     {
-    return;
+    return parentFile;
     }
-
-
-  std::string dotdotDir = dir;
-  std::string::size_type pos = dotdotDir.rfind('/');
-  if(pos != std::string::npos)
+  
+  // is there a parent directory we can check
+  pos = listsDir.rfind('/');
+  // if we could not find the directory return 0
+  if(pos == std::string::npos)
+    {
+    return parentFile;
+    }
+  listsDir = listsDir.substr(0, pos);
+  
+  // is there a CMakeLists.txt file in the parent directory ?
+  parentFile = listsDir;
+  parentFile += "/CMakeLists.txt";
+  if(!cmSystemTools::FileExists(parentFile.c_str()))
     {
-    dotdotDir = dotdotDir.substr(0, pos);
-    this->ParseDirectory(dotdotDir.c_str());
+    parentFile = "";
+    return parentFile;
     }
+  
+  return parentFile;
 }
 
-
 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
 // include and library directories.
 
 void cmMakefile::ExpandVaribles()
 {
   // make sure binary and source dir are defined
-  this->AddDefinition("CMAKE_BINARY_DIR", this->GetOutputHomeDirectory());
+  this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
   this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
 
    // Now expand varibles in the include and link strings

+ 83 - 56
Source/cmMakefile.h

@@ -46,7 +46,7 @@ public:
   /**
    * Read and parse a CMakeLists.txt file.
    */
-  bool ReadMakefile(const char* makefile, bool inheriting = false); 
+  bool ReadListFile(const char* listfile); 
 
   /**
    * Add a wrapper generator.
@@ -141,77 +141,106 @@ public:
    */
   void AddExtraDirectory(const char* dir);
   
+
+  /**
+   * Add an auxiliary directory to the build.
+   */
+  void MakeStartDirectoriesCurrent()
+    {
+      m_cmCurrentDirectory = m_cmStartDirectory;
+      m_CurrentOutputDirectory = m_StartOutputDirectory;
+    }
+  
+  //@{
   /**
-   * Specify the home directory for the build.
+   * Set/Get the home directory (or output directory) in the project. The
+   * home directory is the top directory of the project. It is where
+   * CMakeSetup or configure was run. Remember that CMake processes
+   * CMakeLists files by recursing up the tree starting at the StartDirectory
+   * and going up until it reaches the HomeDirectory.  
    */
   void SetHomeDirectory(const char* dir) 
     {
     m_cmHomeDirectory = dir;
     cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
     }
-
-  /**
-   * Get the home directory for the build.
-   */
   const char* GetHomeDirectory() 
     {
     return m_cmHomeDirectory.c_str();
     }
-
-  /**
-   * Set the current directory in the project.
-   */
-  void SetCurrentDirectory(const char* dir) 
+  void SetHomeOutputDirectory(const char* lib)
     {
-    m_cmCurrentDirectory = dir;
+    m_HomeOutputDirectory = lib;
+    cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
     }
-
-  /**
-   * Get the current directory in the project.
-   */
-  const char* GetCurrentDirectory() 
+  const char* GetHomeOutputDirectory()
     {
-    return m_cmCurrentDirectory.c_str();
+    return m_HomeOutputDirectory.c_str();
     }
-
+  //@}
+  
+  //@{
   /**
-   * Specify the name of the library that is built by this makefile.
+   * Set/Get the start directory (or output directory). The start directory
+   * is the directory of the CMakeLists.txt file that started the current
+   * round of processing. Remember that CMake processes CMakeLists files by
+   * recursing up the tree starting at the StartDirectory and going up until
+   * it reaches the HomeDirectory.  
    */
-  const char* GetLibraryName()
+  void SetStartDirectory(const char* dir) 
     {
-    return m_LibraryName.c_str();
+      m_cmStartDirectory = dir;
+      cmSystemTools::ConvertToUnixSlashes(m_cmStartDirectory);
     }
-
-  /**
-   * Set the name of the library that is built by this makefile.
-   */
-  void SetOutputDirectory(const char* lib)
+  const char* GetStartDirectory() 
     {
-    m_OutputDirectory = lib;
+      return m_cmStartDirectory.c_str();
     }
-
-  /**
-   * Get the name of the library that is built by this makefile.
-   */
-  const char* GetOutputDirectory()
+  void SetStartOutputDirectory(const char* lib)
+    {
+      m_StartOutputDirectory = lib;
+      cmSystemTools::ConvertToUnixSlashes(m_StartOutputDirectory);
+    }
+  const char* GetStartOutputDirectory()
     {
-    return m_OutputDirectory.c_str();
+      return m_StartOutputDirectory.c_str();
     }
+  //@}
 
+  //@{
   /**
-   * Set the name of the current output directory.
+   * Set/Get the current directory (or output directory) in the project. The
+   * current directory is the directory of the CMakeLists.txt file that is
+   * currently being processed. Remember that CMake processes CMakeLists
+   * files by recursing up the tree starting at the StartDirectory and going
+   * up until it reaches the HomeDirectory.  
    */
-  void SetOutputHomeDirectory(const char* lib)
+  void SetCurrentDirectory(const char* dir) 
     {
-    m_OutputHomeDirectory = lib;
+      m_cmCurrentDirectory = dir;
+      cmSystemTools::ConvertToUnixSlashes(m_cmCurrentDirectory);
     }
-
+  const char* GetCurrentDirectory() 
+    {
+      return m_cmCurrentDirectory.c_str();
+    }
+  void SetCurrentOutputDirectory(const char* lib)
+    {
+      m_CurrentOutputDirectory = lib;
+      cmSystemTools::ConvertToUnixSlashes(m_CurrentOutputDirectory);
+    }
+  const char* GetCurrentOutputDirectory()
+    {
+      return m_CurrentOutputDirectory.c_str();
+    }
+  //@}
+  
   /**
-   * Get the name of the current output directory.
+   * Specify the name of the library that is built by this makefile.
    */
-  const char* GetOutputHomeDirectory()
+  const char* GetLibraryName()
     {
-    return m_OutputHomeDirectory.c_str();
+    return m_LibraryName.c_str();
     }
 
   /**
@@ -226,10 +255,7 @@ public:
    * Return a boolean flag indicating whether the build generates
    * any executables.
    */
-  bool HasExecutables() 
-    {
-    return m_Executables;
-    }
+  bool HasExecutables();
 
   /**
    * Get a list of include directories in the build.
@@ -315,13 +341,16 @@ public:
    */
   void ExpandVariblesInString(std::string& source);
 protected:
-  bool m_Executables;
   std::string m_Prefix;
   std::vector<std::string> m_AuxSourceDirectories; // 
-  std::string m_OutputDirectory; // Current output directory for makefile
-  std::string m_OutputHomeDirectory; // Top level output directory
-  std::string m_cmHomeDirectory; // Home directory for source
-  std::string m_cmCurrentDirectory; // current directory in source
+
+  std::string m_cmCurrentDirectory; 
+  std::string m_CurrentOutputDirectory; 
+  std::string m_cmStartDirectory; 
+  std::string m_StartOutputDirectory; 
+  std::string m_cmHomeDirectory; 
+  std::string m_HomeOutputDirectory;
+
   std::string m_LibraryName;	// library name
   std::string m_ProjectName;	// project name
   std::vector<cmClassFile> m_Classes; // list of classes in makefile
@@ -333,7 +362,6 @@ protected:
   std::vector<std::string> m_LinkLibrariesWin32;
   std::vector<std::string> m_LinkLibrariesUnix;
   std::string m_DefineFlags;
-  std::string m_SourceHomeDirectory;
   struct customCommand
   {
     std::string m_Source;
@@ -350,12 +378,11 @@ protected:
   cmMakefileGenerator* m_MakefileGenerator;
   
 private:
-   /**
-   * Look for CMakeLists.txt files to parse in dir,
-   * then in dir's parents, until the SourceHome directory
-   * is found.
+  /**
+   * Get the name of the parent directories CMakeLists file
+   * given a current CMakeLists file name
    */
-  void ParseDirectory(const char* dir);
+  std::string GetParentListFileName(const char *listFileName);
 
   /**
    * Parse a file for includes links and libs

+ 11 - 0
Source/cmProjectCommand.cxx

@@ -24,6 +24,17 @@ bool cmProjectCommand::Invoke(std::vector<std::string>& args)
     return false;
     }
   m_Makefile->SetProjectName(args[0].c_str());
+
+  std::string bindir = args[0];
+  bindir += "_BINARY_DIR";
+  std::string srcdir = args[0];
+  srcdir += "_SOURCE_DIR";
+  
+  m_Makefile->AddDefinition(bindir.c_str(),
+	  m_Makefile->GetCurrentOutputDirectory());
+  m_Makefile->AddDefinition(srcdir.c_str(),
+	  m_Makefile->GetCurrentDirectory());
+  
   return true;
 }
 

+ 12 - 2
Source/cmProjectCommand.h

@@ -24,7 +24,8 @@
  *
  * cmProjectCommand is used to specify a name for this build project.
  * It is defined once per set of CMakeList.txt files (including
- * all subdirectories).
+ * all subdirectories). Currently it just sets the name of the workspace
+ * file for Microsoft Visual C++
  */
 class cmProjectCommand : public cmCommand
 {
@@ -48,6 +49,15 @@ public:
    */
   virtual const char* GetName() {return "PROJECT";}
 
+  /**
+   * This determines if the command gets propagated down
+   * to makefiles located in subdirectories.
+   */
+  virtual bool IsInherited() 
+    {
+    return true;
+    }
+
   /**
    * Succinct documentation.
    */
@@ -62,7 +72,7 @@ public:
   virtual const char* GetFullDocumentation()
     {
     return
-      "PROJECT(projectname)\n";
+      "PROJECT(projectname) Sets the name of the Microsoft workspace .dsw file. Does nothing on UNIX currently\n";
     }
 };