diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 817ee9f74..37ab5b30f 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -56,8 +56,6 @@ SET(SRCS cmListFileLexer.c cmLocalGenerator.cxx cmLocalGenerator.h - cmLocalUnixMakefileGenerator.cxx - cmLocalUnixMakefileGenerator.h cmLocalUnixMakefileGenerator2.cxx cmLocalXCodeGenerator.cxx cmMakeDepend.cxx @@ -292,6 +290,17 @@ IF(BUILD_TESTING) --build-two-config --test-command simple) + ADD_TEST(OutOfSource ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/OutOfSource" + "${CMake_BINARY_DIR}/Tests/OutOfSource" + --build-generator ${CMAKE_GENERATOR} + --build-project OutOfSource + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command + "${CMake_BINARY_DIR}/Tests/OutOfSource/SubDir/OutOfSourceSubdir/simple") + ADD_TEST(PreOrder ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/PreOrder" diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx index 75adee3c2..802a9a548 100644 --- a/Source/cmEnableTestingCommand.cxx +++ b/Source/cmEnableTestingCommand.cxx @@ -15,6 +15,7 @@ =========================================================================*/ #include "cmEnableTestingCommand.h" +#include "cmSubDirectory.h" // we do this in the final pass so that we now the subdirs have all // been defined @@ -64,18 +65,19 @@ void cmEnableTestingCommand::FinalPass() if (!m_Makefile->GetSubDirectories().empty()) { fout << "SUBDIRS("; - const std::vector >& subdirs = m_Makefile->GetSubDirectories(); - std::vector >::const_iterator i = subdirs.begin(); - fout << (*i).first.c_str(); + const std::vector& subdirs + = m_Makefile->GetSubDirectories(); + std::vector::const_iterator i = subdirs.begin(); + fout << (*i).SourcePath.c_str(); ++i; for(; i != subdirs.end(); ++i) { - fout << " " << i->first.c_str(); + fout << " " << i->SourcePath.c_str(); } fout << ")" << std::endl << std::endl;; } fout.close(); - + return; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 66c5b7991..9dc56c890 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -18,6 +18,8 @@ #include "cmLocalGenerator.h" #include "cmake.h" #include "cmMakefile.h" +#include "cmSubDirectory.h" + #include // required for atof #if defined(_WIN32) && !defined(__CYGWIN__) @@ -580,32 +582,29 @@ void cmGlobalGenerator::RecursiveConfigure(cmLocalGenerator *lg, lg->Configure(); // get all the subdirectories - std::vector > subdirs = lg->GetMakefile()->GetSubDirectories(); + std::vector subdirs = + lg->GetMakefile()->GetSubDirectories(); + float progressPiece = (endProgress - startProgress)/(1.0f+subdirs.size()); m_CMakeInstance->UpdateProgress("Configuring", startProgress + progressPiece); // for each subdir recurse - unsigned int i; - for (i = 0; i < subdirs.size(); ++i) + std::vector::const_iterator sdi = subdirs.begin(); + int i; + for (i = 0; sdi != subdirs.end(); ++sdi, ++i) { cmLocalGenerator *lg2 = this->CreateLocalGenerator(); lg2->SetParent(lg); m_LocalGenerators.push_back(lg2); // add the subdir to the start output directory - std::string outdir = lg->GetMakefile()->GetStartOutputDirectory(); - outdir += "/"; - outdir += subdirs[i].first; - lg2->GetMakefile()->SetStartOutputDirectory(outdir.c_str()); - lg2->SetExcludeAll(!subdirs[i].second); + lg2->GetMakefile()->SetStartOutputDirectory(sdi->BinaryPath.c_str()); + lg2->SetExcludeAll(!sdi->IncludeTopLevel); // add the subdir to the start source directory - std::string currentDir = lg->GetMakefile()->GetStartDirectory(); - currentDir += "/"; - currentDir += subdirs[i].first; - lg2->GetMakefile()->SetStartDirectory(currentDir.c_str()); + lg2->GetMakefile()->SetStartDirectory(sdi->SourcePath.c_str()); lg2->GetMakefile()->MakeStartDirectoriesCurrent(); - + this->RecursiveConfigure(lg2, startProgress + (i+1.0f)*progressPiece, startProgress + (i+2.0f)*progressPiece); diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 450bc5701..aec0eefe8 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -210,7 +210,7 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout, this->WriteDSWHeader(fout); // Get the home directory with the trailing slash - std::string homedir = root->GetMakefile()->GetCurrentDirectory(); + std::string homedir = root->GetMakefile()->GetStartOutputDirectory(); homedir += "/"; unsigned int i; @@ -227,7 +227,7 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout, cmMakefile* mf = generators[i]->GetMakefile(); // Get the source directory from the makefile - std::string dir = mf->GetStartDirectory(); + std::string dir = mf->GetStartOutputDirectory(); // remove the home directory and / from the source directory // this gives a relative path cmSystemTools::ReplaceString(dir, homedir.c_str(), ""); diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 35283df6a..e5583c12a 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -48,9 +48,9 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(std::ostream& fout, // Write out the header for a SLN file this->WriteSLNHeader(fout); - // Get the home directory with the trailing slash - std::string homedir = root->GetMakefile()->GetCurrentDirectory(); - homedir += "/"; + // Get the start directory with the trailing slash + std::string rootdir = root->GetMakefile()->GetStartOutputDirectory(); + rootdir += "/"; bool doneAllBuild = false; bool doneRunTests = false; bool doneInstall = false; @@ -67,10 +67,10 @@ void cmGlobalVisualStudio71Generator::WriteSLNFile(std::ostream& fout, cmMakefile* mf = generators[i]->GetMakefile(); // Get the source directory from the makefile - std::string dir = mf->GetStartDirectory(); + std::string dir = mf->GetStartOutputDirectory(); // remove the home directory and / from the source directory // this gives a relative path - cmSystemTools::ReplaceString(dir, homedir.c_str(), ""); + cmSystemTools::ReplaceString(dir, rootdir.c_str(), ""); // Get the list of create dsp files names from the cmVCProjWriter, more // than one dsp could have been created per input CMakeLists.txt file diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index fb6e8c4d0..238d392b8 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -327,9 +327,9 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout, // Write out the header for a SLN file this->WriteSLNHeader(fout); - // Get the home directory with the trailing slash - std::string homedir = root->GetMakefile()->GetCurrentDirectory(); - homedir += "/"; + // Get the start directory with the trailing slash + std::string rootdir = root->GetMakefile()->GetStartOutputDirectory(); + rootdir += "/"; bool doneAllBuild = false; bool doneRunTests = false; bool doneInstall = false; @@ -346,10 +346,10 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout, cmMakefile* mf = generators[i]->GetMakefile(); // Get the source directory from the makefile - std::string dir = mf->GetStartDirectory(); + std::string dir = mf->GetStartOutputDirectory(); // remove the home directory and / from the source directory // this gives a relative path - cmSystemTools::ReplaceString(dir, homedir.c_str(), ""); + cmSystemTools::ReplaceString(dir, rootdir.c_str(), ""); // Get the list of create dsp files names from the cmVCProjWriter, more // than one dsp could have been created per input CMakeLists.txt file diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 0c7ea75c8..504b624e7 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -20,6 +20,7 @@ #include "cmMakefile.h" #include "cmGeneratedFileStream.h" #include "cmSourceFile.h" +#include "cmSubDirectory.h" #include "cmOrderLinkDirectories.h" cmLocalGenerator::cmLocalGenerator() @@ -318,12 +319,11 @@ void cmLocalGenerator::GenerateInstallRules() cmMakefile* mf = this->GetMakefile(); if ( !mf->GetSubDirectories().empty() ) { - const std::vector >& subdirs = mf->GetSubDirectories(); - std::vector >::const_iterator i = subdirs.begin(); + const std::vector& subdirs = mf->GetSubDirectories(); + std::vector::const_iterator i = subdirs.begin(); for(; i != subdirs.end(); ++i) { - std::string odir = mf->GetCurrentOutputDirectory(); - odir += "/" + (*i).first; + std::string odir = i->BinaryPath; cmSystemTools::ConvertToUnixSlashes(odir); fout << "INCLUDE(\"" << odir.c_str() << "/cmake_install.cmake\")" << std::endl; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0932c76eb..0ff37252a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -177,7 +177,6 @@ protected: virtual void AddInstallRule(std::ostream& fout, const char* dest, int type, const char* files, bool optional = false, const char* properties = 0); - bool m_FromTheTop; cmMakefile *m_Makefile; cmGlobalGenerator *m_GlobalGenerator; // members used for relative path function ConvertToMakefilePath diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx index e18d73ab4..b06ba293d 100644 --- a/Source/cmLocalUnixMakefileGenerator.cxx +++ b/Source/cmLocalUnixMakefileGenerator.cxx @@ -22,6 +22,7 @@ #include "cmMakeDepend.h" #include "cmCacheManager.h" #include "cmGeneratedFileStream.h" +#include "cmSubDirectory.h" #include @@ -1738,15 +1739,15 @@ void cmLocalUnixMakefileGenerator::BuildInSubDirectory(std::ostream& fout, void -cmLocalUnixMakefileGenerator:: -OutputSubDirectoryVars(std::ostream& fout, - const char* var, - const char* target, - const char* target1, - const char* target2, - const char* depend, - const std::vector >& SubDirectories, - bool silent, int order) +cmLocalUnixMakefileGenerator +::OutputSubDirectoryVars(std::ostream& fout, + const char* var, + const char* target, + const char* target1, + const char* target2, + const char* depend, + const std::vector& SubDirectories, + bool silent, int order) { if(!depend) { @@ -1762,7 +1763,7 @@ OutputSubDirectoryVars(std::ostream& fout, // make sure all the pre-order subdirectories are fist // other than that keep the same order that the user specified - std::vector > orderedDirs; + std::vector orderedDirs; // collect pre-order first for(ii =0; ii < SubDirectories.size(); ii++) { @@ -1847,7 +1848,7 @@ OutputSubDirectoryVars(std::ostream& fout, void cmLocalUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout) { // Output Sub directory build rules - const std::vector >& SubDirectories + const std::map& SubDirectories = m_Makefile->GetSubDirectories(); if( SubDirectories.size() == 0) diff --git a/Source/cmLocalUnixMakefileGenerator.h b/Source/cmLocalUnixMakefileGenerator.h index 403357eeb..19dbe756f 100644 --- a/Source/cmLocalUnixMakefileGenerator.h +++ b/Source/cmLocalUnixMakefileGenerator.h @@ -23,6 +23,7 @@ class cmDependInformation; class cmMakeDepend; class cmTarget; class cmSourceFile; +class cmSubDirectory; /** \class cmLocalUnixMakefileGenerator * \brief Write a LocalUnix makefiles. @@ -148,8 +149,8 @@ protected: const char* target1, const char* target2, const char* depend, - const std::vector >& - SubDirectories, + const std::map& SubDirectories, bool silent = false, int order = 0); virtual void OutputMakeRule(std::ostream&, diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx index 58dbee866..3d0c57757 100644 --- a/Source/cmLocalUnixMakefileGenerator2.cxx +++ b/Source/cmLocalUnixMakefileGenerator2.cxx @@ -21,6 +21,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmSubDirectory.h" #include "cmake.h" // Include dependency scanners for supported languages. Only the @@ -1313,23 +1314,24 @@ cmLocalUnixMakefileGenerator2 // boolean is true should be included. Keep track of the last // pre-order and last post-order rule created so that ordering can // be enforced. - const std::vector >& - subdirs = m_Makefile->GetSubDirectories(); + const std::vector& subdirs = m_Makefile->GetSubDirectories(); std::string lastPre = ""; std::string lastPost = ""; - for(std::vector >::const_iterator + for(std::vector::const_iterator i = subdirs.begin(); i != subdirs.end(); ++i) { - if(i->second) + if(i->IncludeTopLevel) { // Add the subdirectory rule either for pre-order or post-order. - if(m_Makefile->IsDirectoryPreOrder(i->first.c_str())) + if(i->PreOrder) { - this->WriteSubdirRule(makefileStream, pass, i->first.c_str(), lastPre); + this->WriteSubdirRule(makefileStream, pass, + i->BinaryPath.c_str(), lastPre); } else { - this->WriteSubdirRule(makefileStream, pass, i->first.c_str(), lastPost); + this->WriteSubdirRule(makefileStream, pass, + i->BinaryPath.c_str(), lastPost); } } } @@ -1366,11 +1368,8 @@ cmLocalUnixMakefileGenerator2 // Change back to the starting directory. Any trailing slash must // be removed to avoid problems with Borland Make. - std::string destFull = m_Makefile->GetStartOutputDirectory(); - destFull += "/"; - destFull += subdir; std::string back = - cmSystemTools::RelativePath(destFull.c_str(), + cmSystemTools::RelativePath(subdir, m_Makefile->GetStartOutputDirectory()); if(back.size() && back[back.size()-1] == '/') { @@ -2254,6 +2253,13 @@ cmLocalUnixMakefileGenerator2 { s.replace(pos, 1, "_"); } + + // Replace ":" drive specifier with a single underscore + while((pos = s.find(':')) != std::string::npos) + { + s.replace(pos, 1, "_"); + } + return s; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2acf0df90..c3d711cba 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -195,7 +195,6 @@ void cmMakefile::Print() const std::cout << " m_cmHomeDirectory; " << m_cmHomeDirectory.c_str() << std::endl; std::cout << " m_ProjectName; " << m_ProjectName.c_str() << std::endl; - this->PrintStringVector("m_SubDirectories ", m_SubDirectories); this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories); this->PrintStringVector("m_LinkDirectories", m_LinkDirectories); for( std::vector::const_iterator i = m_SourceGroups.begin(); @@ -343,7 +342,7 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char* external_in) } } - // keep track of the current file being read + // keep track of the current file being read if (filename) { if(m_cmCurrentListFile != filename) @@ -364,35 +363,35 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char* external_in) // rather than the "external" call) if (!external) { - // 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 != "") + // 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(); + if (parentList != "") + { + std::string srcdir = this->GetCurrentDirectory(); + std::string bindir = this->GetCurrentOutputDirectory(); + + std::string::size_type pos = parentList.rfind('/'); + this->SetCurrentDirectory(parentList.substr(0, pos).c_str()); + this->SetCurrentOutputDirectory + ((m_HomeOutputDirectory + + parentList.substr(m_cmHomeDirectory.size(), + pos - m_cmHomeDirectory.size())).c_str()); + + // if not found, oops + if(pos == std::string::npos) { - std::string srcdir = this->GetCurrentDirectory(); - std::string bindir = this->GetCurrentOutputDirectory(); - - std::string::size_type pos = parentList.rfind('/'); - - this->SetCurrentDirectory(parentList.substr(0, pos).c_str()); - this->SetCurrentOutputDirectory((m_HomeOutputDirectory + - parentList.substr(m_cmHomeDirectory.size(), - pos - m_cmHomeDirectory.size())).c_str()); - - // if not found, oops - if(pos == std::string::npos) - { - cmSystemTools::Error("Trailing slash not found"); - } - - this->ReadListFile(parentList.c_str()); - - // restore the current directory - this->SetCurrentDirectory(srcdir.c_str()); - this->SetCurrentOutputDirectory(bindir.c_str()); + cmSystemTools::Error("Trailing slash not found"); } + + this->ReadListFile(parentList.c_str()); + + // restore the current directory + this->SetCurrentDirectory(srcdir.c_str()); + this->SetCurrentOutputDirectory(bindir.c_str()); + } } - + // are we at the start CMakeLists file or are we processing a parent // lists file // @@ -834,24 +833,52 @@ void cmMakefile::AddLinkDirectory(const char* dir) } } -bool cmMakefile::IsDirectoryPreOrder(const char* dir) -{ - return (m_SubDirectoryOrder.find(dir) != m_SubDirectoryOrder.end()); -} - void cmMakefile::AddSubDirectory(const char* sub, bool topLevel, bool preorder) { - if(preorder) + // the source path must be made full if it isn't already + std::string srcPath = sub; + if (!cmSystemTools::FileIsFullPath(srcPath.c_str())) { - m_SubDirectoryOrder[sub] = preorder; + srcPath = this->GetCurrentDirectory(); + srcPath += "/"; + srcPath += sub; } - std::pair p(sub, topLevel); - // make sure it isn't already there - if (std::find(m_SubDirectories.begin(), - m_SubDirectories.end(), p) == m_SubDirectories.end()) + + // binary path must be made full if it isn't already + std::string binPath = sub; + if (!cmSystemTools::FileIsFullPath(binPath.c_str())) { - m_SubDirectories.push_back(p); + binPath = this->GetCurrentOutputDirectory(); + binPath += "/"; + binPath += sub; } + + + this->AddSubDirectory(srcPath.c_str(), binPath.c_str(), topLevel, preorder); +} + + +void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath, + bool topLevel, bool preorder) +{ + // has this directory already been added? If so error + unsigned int i; + for (i = 0; i < m_SubDirectories.size(); ++i) + { + if (m_SubDirectories[i].SourcePath == srcPath) + { + cmSystemTools::Error("Attempt to add subdirectory multiple times for directory.\n", srcPath); + return; + } + } + + // now add it + cmSubDirectory s; + s.SourcePath = srcPath; + s.BinaryPath = binPath; + s.IncludeTopLevel = topLevel; + s.PreOrder = preorder; + m_SubDirectories.push_back(s); } void cmMakefile::AddIncludeDirectory(const char* inc, bool before) @@ -1185,6 +1212,51 @@ void cmMakefile::AddExtraDirectory(const char* dir) m_AuxSourceDirectories.push_back(dir); } +// return the file name for a parent CMakeLists file. It will return the +// parent to the CMakeLists file to the m_CurrentDirectory + + +std::string cmMakefile::GetParentListFileName() +{ + std::string parentFile; + + bool done = false; + cmLocalGenerator *lg = m_LocalGenerator; + cmLocalGenerator *lgp = 0; + + while (!done) + { + // first find the lg for the current directory + if (!strcmp(lg->GetMakefile()->GetStartDirectory(), + this->GetCurrentDirectory())) + { + // now get the parent + lgp = lg->GetParent(); + done = true; + } + else + { + lg = lg->GetParent(); + if (!lg) + { + return parentFile; + } + } + } + + // if we are the top then stop + if (!lgp) + { + return parentFile; + } + + // otherwise get the list file for the parent local generator + parentFile = lgp->GetMakefile()->GetCurrentDirectory(); + parentFile += "/CMakeLists.txt"; + return parentFile; +} + +#if 0 // return the file name for the parent CMakeLists file to the // one passed in. Zero is returned if the CMakeLists file is the @@ -1243,6 +1315,7 @@ std::string cmMakefile::GetParentListFileName(const char *currentFileName) return parentFile; } +#endif // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the // include and library directories. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index a9f159c0a..2fed10dd1 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -24,6 +24,8 @@ #include "cmListFileCache.h" #include "cmCacheManager.h" +#include "cmSubDirectory.h" + #include class cmFunctionBlocker; @@ -212,6 +214,8 @@ public: * Add a subdirectory to the build. */ void AddSubDirectory(const char*, bool includeTopLevel=true, bool preorder = false); + void AddSubDirectory(const char* fullSrcDir,const char *fullBinDir, + bool includeTopLevel=true, bool preorder = false); /** * Add an include directory to the build. @@ -416,7 +420,7 @@ public: /** * Get a list of the build subdirectories. */ - const std::vector >& GetSubDirectories() + const std::vector& GetSubDirectories() { return m_SubDirectories; } @@ -653,9 +657,6 @@ public: */ std::string GetModulesFile(const char* name); - ///! Return true if the directory is preorder. - bool IsDirectoryPreOrder(const char* dir); - ///! Set/Get a property of this directory void SetProperty(const char *prop, const char *value); const char *GetProperty(const char *prop) const; @@ -683,7 +684,8 @@ protected: cmTargets m_Targets; std::vector m_SourceFiles; - std::vector > m_SubDirectories; // list of sub directories + // list of sub directories + std::vector m_SubDirectories; struct StringSet : public std::set { }; @@ -712,10 +714,9 @@ protected: private: /** - * Get the name of the parent directories CMakeLists file - * given a current CMakeLists file name + * Get the name of the parent generator's CMakeLists file */ - std::string GetParentListFileName(const char *listFileName); + std::string GetParentListFileName(); void ReadSources(std::ifstream& fin, bool t); friend class cmMakeDepend; // make depend needs direct access diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index e2c52bd00..56cae3624 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -41,16 +41,33 @@ bool cmSubdirCommand::InitialPass(std::vector const& args) preorder = true; continue; } - std::string directory = std::string(m_Makefile->GetCurrentDirectory()) + - "/" + i->c_str(); - if ( cmSystemTools::FileIsDirectory(directory.c_str()) ) + + // if they specified a relative path then compute the full + std::string srcPath = std::string(m_Makefile->GetCurrentDirectory()) + + "/" + i->c_str(); + if (cmSystemTools::FileIsDirectory(srcPath.c_str())) { - m_Makefile->AddSubDirectory(i->c_str(), intoplevel, preorder); + std::string binPath = + std::string(m_Makefile->GetCurrentOutputDirectory()) + + "/" + i->c_str(); + m_Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(), + intoplevel, preorder); + } + // otherwise it is a full path + else if ( cmSystemTools::FileIsDirectory(i->c_str()) ) + { + // we must compute the binPath from the srcPath, we just take the last + // element from the source path and use that + std::string binPath = + std::string(m_Makefile->GetCurrentOutputDirectory()) + + "/" + cmSystemTools::GetFilenameName(i->c_str()); + m_Makefile->AddSubDirectory(i->c_str(), binPath.c_str(), + intoplevel, preorder); } else { std::string error = "Incorrect SUBDIRS command. Directory: "; - error += directory + " does not exists."; + error += *i + " does not exists."; this->SetError(error.c_str()); res = false; }