diff --git a/CMakeRules.make.in b/CMakeRules.make.in index bfecbf397..875d99f16 100644 --- a/CMakeRules.make.in +++ b/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 diff --git a/CMakeVariables.make.in b/CMakeVariables.make.in index 135b62cba..d1a0bb1c1 100644 --- a/CMakeVariables.make.in +++ b/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@ diff --git a/Source/CMakeBuildTargets.cxx b/Source/CMakeBuildTargets.cxx index e4c9e92b2..876708e87 100644 --- a/Source/CMakeBuildTargets.cxx +++ b/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; diff --git a/Source/CMakeSetupCMD.cxx b/Source/CMakeSetupCMD.cxx index 81db43981..725062918 100644 --- a/Source/CMakeSetupCMD.cxx +++ b/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; } diff --git a/Source/MFCDialog/CMakeSetupDialog.cpp b/Source/MFCDialog/CMakeSetupDialog.cpp index 3f5a26018..036d76cd6 100644 --- a/Source/MFCDialog/CMakeSetupDialog.cpp +++ b/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(); diff --git a/Source/cmClassFile.cxx b/Source/cmClassFile.cxx index a2122c0ec..8e408156c 100644 --- a/Source/cmClassFile.cxx +++ b/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; } diff --git a/Source/cmClassFile.h b/Source/cmClassFile.h index 4004839ea..8a9845ea8 100644 --- a/Source/cmClassFile.h +++ b/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. */ diff --git a/Source/cmConfigureFileNoAutoconf.h b/Source/cmConfigureFileNoAutoconf.h index e14b2cbe5..42a3e3ae5 100644 --- a/Source/cmConfigureFileNoAutoconf.h +++ b/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"; } /** diff --git a/Source/cmDSPMakefile.cxx b/Source/cmDSPMakefile.cxx index 0687c7334..f43afce67 100644 --- a/Source/cmDSPMakefile.cxx +++ b/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) + if (classfile.m_IsExecutable) { - std::string message = "Error Writing "; - message += fname; - Die(message.c_str()); + 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); + } } - 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& 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()); } diff --git a/Source/cmDSPWriter.cxx b/Source/cmDSPWriter.cxx index 0687c7334..f43afce67 100644 --- a/Source/cmDSPWriter.cxx +++ b/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) + if (classfile.m_IsExecutable) { - std::string message = "Error Writing "; - message += fname; - Die(message.c_str()); + 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); + } } - 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& 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()); } diff --git a/Source/cmDSWMakefile.cxx b/Source/cmDSWMakefile.cxx index e8db5d4e6..28bc09da4 100644 --- a/Source/cmDSWMakefile.cxx +++ b/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 current directory in the Source as a full - // path - std::string currentDir = m_Makefile->GetCurrentDirectory(); - currentDir += "/"; - currentDir += subdir; - mf->SetCurrentDirectory(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(); + std::string outdir = m_Makefile->GetStartOutputDirectory(); outdir += "/"; outdir += subdir; - mf->SetOutputDirectory(outdir.c_str()); + mf->SetStartOutputDirectory(outdir.c_str()); + // set the current directory in the Source as a full + // path + std::string currentDir = m_Makefile->GetStartDirectory(); + currentDir += "/"; + currentDir += subdir; + mf->SetStartDirectory(currentDir.c_str()); + // Parse the CMakeLists.txt file + currentDir += "/CMakeLists.txt"; + mf->MakeStartDirectoriesCurrent(); + mf->ReadListFile(currentDir.c_str()); // Create the DSP file mf->GenerateMakefile(); // Look at any sub directories parsed (SUBDIRS) and diff --git a/Source/cmDSWWriter.cxx b/Source/cmDSWWriter.cxx index e8db5d4e6..28bc09da4 100644 --- a/Source/cmDSWWriter.cxx +++ b/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 current directory in the Source as a full - // path - std::string currentDir = m_Makefile->GetCurrentDirectory(); - currentDir += "/"; - currentDir += subdir; - mf->SetCurrentDirectory(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(); + std::string outdir = m_Makefile->GetStartOutputDirectory(); outdir += "/"; outdir += subdir; - mf->SetOutputDirectory(outdir.c_str()); + mf->SetStartOutputDirectory(outdir.c_str()); + // set the current directory in the Source as a full + // path + std::string currentDir = m_Makefile->GetStartDirectory(); + currentDir += "/"; + currentDir += subdir; + mf->SetStartDirectory(currentDir.c_str()); + // Parse the CMakeLists.txt file + currentDir += "/CMakeLists.txt"; + mf->MakeStartDirectoriesCurrent(); + mf->ReadListFile(currentDir.c_str()); // Create the DSP file mf->GenerateMakefile(); // Look at any sub directories parsed (SUBDIRS) and diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 4872d9434..e16ea75f7 100644 --- a/Source/cmMakefile.cxx +++ b/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) { - this->ParseDirectory(m_cmCurrentDirectory.c_str()); + m_cmCurrentDirectory = m_cmCurrentDirectory.substr(0, pos); } + pos = m_CurrentOutputDirectory.rfind('/'); + if(pos != std::string::npos) + { + 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) { - dotdotDir = dotdotDir.substr(0, pos); - this->ParseDirectory(dotdotDir.c_str()); + 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())) + { + 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 diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 2e8b39a66..a23fa110e 100644 --- a/Source/cmMakefile.h +++ b/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,39 +141,100 @@ public: */ void AddExtraDirectory(const char* dir); + /** - * Specify the home directory for the build. + * Add an auxiliary directory to the build. + */ + void MakeStartDirectoriesCurrent() + { + m_cmCurrentDirectory = m_cmStartDirectory; + m_CurrentOutputDirectory = m_StartOutputDirectory; + } + + //@{ + /** + * 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(); } - + void SetHomeOutputDirectory(const char* lib) + { + m_HomeOutputDirectory = lib; + cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory); + } + const char* GetHomeOutputDirectory() + { + return m_HomeOutputDirectory.c_str(); + } + //@} + + //@{ /** - * Set the current directory in the project. + * 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. + */ + void SetStartDirectory(const char* dir) + { + m_cmStartDirectory = dir; + cmSystemTools::ConvertToUnixSlashes(m_cmStartDirectory); + } + const char* GetStartDirectory() + { + return m_cmStartDirectory.c_str(); + } + void SetStartOutputDirectory(const char* lib) + { + m_StartOutputDirectory = lib; + cmSystemTools::ConvertToUnixSlashes(m_StartOutputDirectory); + } + const char* GetStartOutputDirectory() + { + return m_StartOutputDirectory.c_str(); + } + //@} + + //@{ + /** + * 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 SetCurrentDirectory(const char* dir) { - m_cmCurrentDirectory = dir; + m_cmCurrentDirectory = dir; + cmSystemTools::ConvertToUnixSlashes(m_cmCurrentDirectory); } - - /** - * Get the current directory in the project. - */ const char* GetCurrentDirectory() { - return m_cmCurrentDirectory.c_str(); + 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(); + } + //@} + /** * Specify the name of the library that is built by this makefile. */ @@ -182,38 +243,6 @@ public: return m_LibraryName.c_str(); } - /** - * Set the name of the library that is built by this makefile. - */ - void SetOutputDirectory(const char* lib) - { - m_OutputDirectory = lib; - } - - /** - * Get the name of the library that is built by this makefile. - */ - const char* GetOutputDirectory() - { - return m_OutputDirectory.c_str(); - } - - /** - * Set the name of the current output directory. - */ - void SetOutputHomeDirectory(const char* lib) - { - m_OutputHomeDirectory = lib; - } - - /** - * Get the name of the current output directory. - */ - const char* GetOutputHomeDirectory() - { - return m_OutputHomeDirectory.c_str(); - } - /** * Get a list of the build subdirectories. */ @@ -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 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 m_Classes; // list of classes in makefile @@ -333,7 +362,6 @@ protected: std::vector m_LinkLibrariesWin32; std::vector 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 diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index b35e15d0e..0eff60770 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -24,6 +24,17 @@ bool cmProjectCommand::Invoke(std::vector& 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; } diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index 3a705e8dd..fe395b056 100644 --- a/Source/cmProjectCommand.h +++ b/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"; } };