summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalUnixMakefileGenerator2.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2004-10-29 22:15:59 (GMT)
committerBrad King <brad.king@kitware.com>2004-10-29 22:15:59 (GMT)
commit3bb39d4390413f346bad5030d84c926fc919d9de (patch)
treec4ef71e43d784d1fd518b259679d4f7c36f9e43e /Source/cmLocalUnixMakefileGenerator2.cxx
parentbf2a2b203f70f9403746a7a5e68797edc8941349 (diff)
downloadCMake-3bb39d4390413f346bad5030d84c926fc919d9de.zip
CMake-3bb39d4390413f346bad5030d84c926fc919d9de.tar.gz
CMake-3bb39d4390413f346bad5030d84c926fc919d9de.tar.bz2
ENH: Added framework for subdirectory traversal.
Diffstat (limited to 'Source/cmLocalUnixMakefileGenerator2.cxx')
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.cxx121
1 files changed, 120 insertions, 1 deletions
diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx
index 5052996..d393c00 100644
--- a/Source/cmLocalUnixMakefileGenerator2.cxx
+++ b/Source/cmLocalUnixMakefileGenerator2.cxx
@@ -89,6 +89,9 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
// Write the directory-level build rules.
this->WriteAllRule(makefileStream);
+ // Write the subdirectory driver rules.
+ this->WriteSubdirRules(makefileStream);
+
// Write include statements to get rules for each target.
this->WriteTargetIncludes(makefileStream);
@@ -695,19 +698,29 @@ cmLocalUnixMakefileGenerator2
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
// Write the main entry point target. This must be the VERY first
- // target so that make with no arguments will run it.
+ // target so that make with no arguments will run it. The
+ // dependencies and commands generated for this rule must not depend
+ // on listfile contents because the build system check might
+ // regenerate the makefile but it might not get read again by make
+ // before the commands run.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
// Check the build system in this directory.
depends.push_back("cmake_check_build_system");
+ // Recursively build pre-order directories.
+ commands.push_back(this->GetRecursiveMakeCall("all.subdirs.pre"));
+
// Recursively build dependencies.
commands.push_back(this->GetRecursiveMakeCall("all.depends"));
// Recursively build targets.
commands.push_back(this->GetRecursiveMakeCall("all.build"));
+ // Recursively build post-order directories.
+ commands.push_back(this->GetRecursiveMakeCall("all.subdirs.post"));
+
// Write the rule.
std::string preEcho = "Entering directory ";
preEcho += m_Makefile->GetStartOutputDirectory();
@@ -891,6 +904,88 @@ cmLocalUnixMakefileGenerator2
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
+::WriteSubdirRules(std::ostream& makefileStream)
+{
+ // Write the section header.
+ this->WriteDivider(makefileStream);
+ makefileStream
+ << "# Subdirectory driver targets.\n"
+ << "\n";
+
+ // Iterate through subdirectories. Only entries in which the
+ // 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<std::pair<cmStdString, bool> >&
+ subdirs = m_Makefile->GetSubDirectories();
+ std::string lastPre = "";
+ std::string lastPost = "";
+ for(std::vector<std::pair<cmStdString, bool> >::const_iterator
+ i = subdirs.begin(); i != subdirs.end(); ++i)
+ {
+ if(i->second)
+ {
+ // Construct the name of the subdirectory rule.
+ std::string tgt = this->GetSubdirTargetName(i->first.c_str());
+
+ // Add the subdirectory rule either for pre-order or post-order.
+ if(m_Makefile->IsDirectoryPreOrder(i->first.c_str()))
+ {
+ this->WriteSubdirRule(makefileStream, tgt.c_str(), lastPre.c_str());
+ lastPre = tgt;
+ }
+ else
+ {
+ this->WriteSubdirRule(makefileStream, tgt.c_str(), lastPost.c_str());
+ lastPost = tgt;
+ }
+ }
+ }
+
+ // Write the subdir driver rules. Hook them to the last
+ // subdirectory of their corresponding order.
+ std::vector<std::string> pre_depends;
+ std::vector<std::string> post_depends;
+ std::vector<std::string> no_commands;
+ if(lastPre.size())
+ {
+ pre_depends.push_back(lastPre);
+ }
+ if(lastPost.size())
+ {
+ post_depends.push_back(lastPost);
+ }
+ this->WriteMakeRule(makefileStream,
+ "Pre-order subdirectory driver target.", 0,
+ "all.subdirs.pre", pre_depends, no_commands);
+ this->WriteMakeRule(makefileStream,
+ "Post-order subdirectory driver target.", 0,
+ "all.subdirs.post", post_depends, no_commands);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
+::WriteSubdirRule(std::ostream& makefileStream, const char* tgt,
+ const char* last)
+{
+ // TODO: Generate commands to cd into subdir (CONTINUE HERE).
+ std::vector<std::string> depends;
+ std::vector<std::string> no_commands;
+
+ // Depend on the last directory written out to enforce ordering.
+ if(last && *last)
+ {
+ depends.push_back(last);
+ }
+
+ // Write the rule.
+ this->WriteMakeRule(makefileStream, 0, 0, tgt, depends, no_commands);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
::WriteRequiresRule(std::ostream& ruleFileStream, const cmTarget& target,
const char* targetFullPath)
{
@@ -1361,6 +1456,30 @@ cmLocalUnixMakefileGenerator2
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator2
+::GetSubdirTargetName(const char* subdir)
+{
+ // Convert the subdirectory name to a valid make target name.
+ std::string s = "subdir_";
+ s += subdir;
+
+ // Replace "../" with 3 underscores. This allows one .. at the beginning.
+ size_t pos = s.find("../");
+ if(pos != std::string::npos)
+ {
+ s.replace(pos, 3, "___");
+ }
+
+ // Replace "/" directory separators with a single underscore.
+ while((pos = s.find('/')) != std::string::npos)
+ {
+ s.replace(pos, 1, "_");
+ }
+ return s;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator2
::GetObjectFileName(const cmTarget& target,
const cmSourceFile& source)
{