From 8b0b749a11138107189f9264494f828778c0cf8b Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Fri, 23 Apr 2004 12:52:48 -0400 Subject: ENH: add SUBDIR PREORDER and fix clean for non-relative paths --- Source/CMakeLists.txt | 10 +++ Source/cmLocalUnixMakefileGenerator.cxx | 116 +++++++++++++++++++++++++------- Source/cmLocalUnixMakefileGenerator.h | 4 +- Source/cmMakefile.cxx | 11 ++- Source/cmMakefile.h | 16 ++--- Source/cmSubdirCommand.cxx | 8 ++- Tests/PreOrder/CMakeLists.txt | 6 ++ Tests/PreOrder/Library/CMakeLists.txt | 2 + Tests/PreOrder/Library/simpleLib.cxx | 3 + Tests/PreOrder/simple.cxx | 6 ++ 10 files changed, 141 insertions(+), 41 deletions(-) create mode 100644 Tests/PreOrder/CMakeLists.txt create mode 100644 Tests/PreOrder/Library/CMakeLists.txt create mode 100644 Tests/PreOrder/Library/simpleLib.cxx create mode 100644 Tests/PreOrder/simple.cxx diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3ba2ff1..13b2416 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -228,6 +228,16 @@ IF(BUILD_TESTING) --build-two-config --test-command simple) + ADD_TEST(PreOrder ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/PreOrder" + "${CMake_BINARY_DIR}/Tests/PreOrder" + --build-generator ${CMAKE_GENERATOR} + --build-project PreOrder + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command simple) + ADD_TEST(conly ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/COnly" diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx index be05453..3bf17e1 100644 --- a/Source/cmLocalUnixMakefileGenerator.cxx +++ b/Source/cmLocalUnixMakefileGenerator.cxx @@ -1781,13 +1781,20 @@ void cmLocalUnixMakefileGenerator::OutputBuildTargetInDirWindows(std::ostream& f const char* library, const char* fullpath) { - std::string jumpBack = - cmSystemTools::RelativePath(cmSystemTools::GetProgramPath(path).c_str(), - m_Makefile->GetCurrentOutputDirectory()); + std::string jumpBack; + if(m_UseRelativePaths) + { + cmSystemTools::Message("using relative paths??"); + jumpBack = cmSystemTools::RelativePath(cmSystemTools::GetProgramPath(path).c_str(), + m_Makefile->GetCurrentOutputDirectory()); + } + else + { + jumpBack = m_Makefile->GetCurrentOutputDirectory(); + } jumpBack = this->ConvertToOutputForExisting(jumpBack.c_str()); std::string wpath = this->ConvertToOutputForExisting(path); std::string wfullpath = this->ConvertToOutputForExisting(fullpath); - fout << wfullpath << ":\n\tcd " << wpath << "\n" << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) cmake.depends\n" @@ -2008,23 +2015,32 @@ BuildInSubDirectoryWindows(std::ostream& fout, } fout << "\t$(MAKE) -$(MAKEFLAGS) $(MAKESILENT) " << target2 << "\n"; } - std::string currentDir = dir; - cmSystemTools::ConvertToUnixSlashes(currentDir); - std::string cdback = ".."; - unsigned int i = 0; - if(currentDir.size() > 2 && currentDir[0] == '.' && currentDir[1] == '/') - { - // start past ./ if it starts with ./ - i = 2; - } - for(; i < currentDir.size(); ++i) + std::string currentDir; + if(m_UseRelativePaths) { - if(currentDir[i] == '/') + currentDir = dir; + cmSystemTools::ConvertToUnixSlashes(currentDir); + std::string cdback = ".."; + unsigned int i = 0; + if(currentDir.size() > 2 && currentDir[0] == '.' && currentDir[1] == '/') { - cdback += "/.."; + // start past ./ if it starts with ./ + i = 2; } + for(; i < currentDir.size(); ++i) + { + if(currentDir[i] == '/') + { + cdback += "/.."; + } + } + fout << "\tcd " << this->ConvertToOutputForExisting(cdback.c_str()) << "\n\n"; + } + else + { + currentDir = m_Makefile->GetCurrentOutputDirectory(); + fout << "\tcd " << this->ConvertToOutputForExisting(currentDir.c_str()) << "\n\n"; } - fout << "\tcd " << this->ConvertToOutputForExisting(cdback.c_str()) << "\n\n"; } @@ -2074,7 +2090,7 @@ OutputSubDirectoryVars(std::ostream& fout, const char* target2, const char* depend, const std::vector >& SubDirectories, - bool silent) + bool silent, int order) { if(!depend) { @@ -2087,27 +2103,68 @@ OutputSubDirectoryVars(std::ostream& fout, fout << "# Variable for making " << target << " in subdirectories.\n"; fout << var << " = "; unsigned int ii; + + // make sure all the pre-order subdirectories are fist + // other than that keep the same order that the user specified + std::vector > orderedDirs; + // collect pre-order first + for(ii =0; ii < SubDirectories.size(); ii++) + { + if(m_Makefile->IsDirectoryPreOrder(SubDirectories[ii].first.c_str())) + { + orderedDirs.push_back(SubDirectories[ii]); + } + } + // now collect post order dirs for(ii =0; ii < SubDirectories.size(); ii++) + { + if(!m_Makefile->IsDirectoryPreOrder(SubDirectories[ii].first.c_str())) + { + orderedDirs.push_back(SubDirectories[ii]); + } + } + + for(ii =0; ii < orderedDirs.size(); ii++) { - if(!SubDirectories[ii].second) + if(!orderedDirs[ii].second) + { + continue; + } + if(order == 1 && m_Makefile->IsDirectoryPreOrder(orderedDirs[ii].first.c_str())) + { + continue; + } + if(order == 2 && !m_Makefile->IsDirectoryPreOrder(orderedDirs[ii].first.c_str())) { continue; } + fout << " \\\n"; - std::string subdir = FixDirectoryName(SubDirectories[ii].first.c_str()); + std::string subdir = FixDirectoryName(orderedDirs[ii].first.c_str()); fout << target << "_" << subdir.c_str(); } fout << " \n\n"; fout << "# Targets for making " << target << " in subdirectories.\n"; std::string last = ""; - for(unsigned int cc =0; cc < SubDirectories.size(); cc++) + for(unsigned int cc =0; cc < orderedDirs.size(); cc++) { - if(!SubDirectories[cc].second) + if(!orderedDirs[cc].second) { continue; + } + std::string subdir = FixDirectoryName(orderedDirs[cc].first.c_str()); + if(order == 1 && m_Makefile->IsDirectoryPreOrder(orderedDirs[cc].first.c_str())) + { + last = subdir; + continue; + } + if(order == 2 && !m_Makefile->IsDirectoryPreOrder(orderedDirs[cc].first.c_str())) + { + last = subdir; + continue; } - std::string subdir = FixDirectoryName(SubDirectories[cc].first.c_str()); + fout << target << "_" << subdir.c_str() << ": " << depend; // Make each subdirectory depend on previous one. This forces @@ -2122,7 +2179,7 @@ OutputSubDirectoryVars(std::ostream& fout, last = subdir; std::string dir = m_Makefile->GetCurrentOutputDirectory(); dir += "/"; - dir += SubDirectories[cc].first; + dir += orderedDirs[cc].first; this->BuildInSubDirectory(fout, dir.c_str(), target1, target2, silent); } @@ -2148,7 +2205,14 @@ void cmLocalUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout) "default_target", 0, "$(TARGETS)", SubDirectories, - false); + false, 1); + this->OutputSubDirectoryVars(fout, + "SUBDIR_PREORDER_BUILD", + "default_target", + "default_target", + 0, "$(TARGETS)", + SubDirectories, + false, 2); this->OutputSubDirectoryVars(fout, "SUBDIR_CLEAN", "clean", "clean", 0, 0, @@ -2442,7 +2506,7 @@ void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout) this->OutputMakeRule(fout, "default build rule", "all", - "cmake.depends $(TARGETS) $(SUBDIR_BUILD)", + "cmake.depends $(SUBDIR_PREORDER_BUILD) $(TARGETS) $(SUBDIR_BUILD)", 0); this->OutputMakeRule(fout, "clean generated files", diff --git a/Source/cmLocalUnixMakefileGenerator.h b/Source/cmLocalUnixMakefileGenerator.h index 713d1b5..c5a8a73 100644 --- a/Source/cmLocalUnixMakefileGenerator.h +++ b/Source/cmLocalUnixMakefileGenerator.h @@ -151,7 +151,7 @@ protected: const char* target1, const char* target2, bool silent = false); - + ///! order == 0, then all subdirs are output, 1 = post order, 2 = preorder virtual void OutputSubDirectoryVars(std::ostream& fout, const char* var, const char* target, @@ -160,7 +160,7 @@ protected: const char* depend, const std::vector >& SubDirectories, - bool silent = false); + bool silent = false, int order = 0); virtual void OutputMakeRule(std::ostream&, const char* comment, diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index aa8b1af..b073bf9 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -840,8 +840,17 @@ void cmMakefile::AddLinkDirectory(const char* dir) } } -void cmMakefile::AddSubDirectory(const char* sub, bool topLevel) +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) + { + m_SubDirectoryOrder[sub] = preorder; + } std::pair p(sub, topLevel); // make sure it isn't already there if (std::find(m_SubDirectories.begin(), diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 194729e..39c937a 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -216,7 +216,7 @@ public: /** * Add a subdirectory to the build. */ - void AddSubDirectory(const char*, bool includeTopLevel=true); + void AddSubDirectory(const char*, bool includeTopLevel=true, bool preorder = false); /** * Add an include directory to the build. @@ -276,16 +276,6 @@ public: const std::vector &srcs); /** - * Add a class/source file to the build. - */ - //void AddSource(cmSourceFile& ,const char *srcListName); - - /** - * Remove a class/source file from the build. - */ - //void RemoveSource(cmSourceFile& ,const char *srcListName); - - /** * Add a source group for consideration when adding a new source. */ void AddSourceGroup(const char* name, const char* regex=0); @@ -648,6 +638,9 @@ public: * Return a location of a file in cmake or custom modules directory */ std::string GetModulesFile(const char* name); + + ///! Return true if the directory is preorder. + bool IsDirectoryPreOrder(const char* dir); protected: // add link libraries and directories to the target @@ -720,6 +713,7 @@ private: typedef std::map StringStringMap; StringStringMap m_MacrosMap; + std::map m_SubDirectoryOrder; // used in AddDefinition for performance improvement DefinitionMap::key_type m_TemporaryDefinitionKey; diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index 3bcd1a0..e2c52bd 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -26,6 +26,7 @@ bool cmSubdirCommand::InitialPass(std::vector const& args) } bool res = true; bool intoplevel = true; + bool preorder = false; for(std::vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -35,11 +36,16 @@ bool cmSubdirCommand::InitialPass(std::vector const& args) intoplevel = false; continue; } + if(*i == "PREORDER") + { + preorder = true; + continue; + } std::string directory = std::string(m_Makefile->GetCurrentDirectory()) + "/" + i->c_str(); if ( cmSystemTools::FileIsDirectory(directory.c_str()) ) { - m_Makefile->AddSubDirectory(i->c_str(), intoplevel); + m_Makefile->AddSubDirectory(i->c_str(), intoplevel, preorder); } else { diff --git a/Tests/PreOrder/CMakeLists.txt b/Tests/PreOrder/CMakeLists.txt new file mode 100644 index 0000000..a4a96fb --- /dev/null +++ b/Tests/PreOrder/CMakeLists.txt @@ -0,0 +1,6 @@ +# a simple test case +PROJECT (PreOrder) +SET(CMAKE_IGNORE_DEPENDENCIES_ORDERING 1) +SUBDIRS(PREORDER Library) +ADD_EXECUTABLE (simple simple.cxx) +TARGET_LINK_LIBRARIES(simple simpleLib) diff --git a/Tests/PreOrder/Library/CMakeLists.txt b/Tests/PreOrder/Library/CMakeLists.txt new file mode 100644 index 0000000..6c011ec --- /dev/null +++ b/Tests/PreOrder/Library/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_LIBRARY(simpleLib simpleLib.cxx ) + diff --git a/Tests/PreOrder/Library/simpleLib.cxx b/Tests/PreOrder/Library/simpleLib.cxx new file mode 100644 index 0000000..281d888 --- /dev/null +++ b/Tests/PreOrder/Library/simpleLib.cxx @@ -0,0 +1,3 @@ +void simpleLib() +{ +} diff --git a/Tests/PreOrder/simple.cxx b/Tests/PreOrder/simple.cxx new file mode 100644 index 0000000..ef26e79 --- /dev/null +++ b/Tests/PreOrder/simple.cxx @@ -0,0 +1,6 @@ +extern void simpleLib(); +int main () +{ + simpleLib(); + return 0; +} -- cgit v0.12