summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalUnixMakefileGenerator2.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2004-10-27 14:45:18 (GMT)
committerBrad King <brad.king@kitware.com>2004-10-27 14:45:18 (GMT)
commit8e0985f9f1785fc8fdc7c6c35bb215bf2070804d (patch)
tree0229f636885478c1beabbe3cf0b80f59f49aaab2 /Source/cmLocalUnixMakefileGenerator2.cxx
parent235bf2547c40e9aba71ff289384be1ac8856f213 (diff)
downloadCMake-8e0985f9f1785fc8fdc7c6c35bb215bf2070804d.zip
CMake-8e0985f9f1785fc8fdc7c6c35bb215bf2070804d.tar.gz
CMake-8e0985f9f1785fc8fdc7c6c35bb215bf2070804d.tar.bz2
ENH: Added executable dependencies on libraries including jump-and-build support.
Diffstat (limited to 'Source/cmLocalUnixMakefileGenerator2.cxx')
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.cxx185
1 files changed, 174 insertions, 11 deletions
diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx
index 04d98b1..6e90fd8 100644
--- a/Source/cmLocalUnixMakefileGenerator2.cxx
+++ b/Source/cmLocalUnixMakefileGenerator2.cxx
@@ -91,17 +91,11 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
runRule += " --check-rerun ";
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
- // Most unix makes will pass the command line flags to make down to
- // sub-invoked makes via an environment variable. However, some
- // makes do not support that, so you have to pass the flags
- // explicitly.
- const char* depRule = "$(MAKE) -f Makefile2 $(MAKESILENT) all.depends";
- const char* allRule = "$(MAKE) -f Makefile2 $(MAKESILENT) all";
- if(m_PassMakeflags)
- {
- depRule = "$(MAKE) -f Makefile2 $(MAKESILENT) -$(MAKEFLAGS) all.depends";
- allRule = "$(MAKE) -f Makefile2 $(MAKESILENT) -$(MAKEFLAGS) all";
- }
+ // Construct recursive calls for the "all" rules.
+ std::string depRule;
+ std::string allRule;
+ this->AppendRecursiveMake(depRule, "Makefile2", "all.depends");
+ this->AppendRecursiveMake(allRule, "Makefile2", "all");
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
@@ -179,6 +173,9 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
<< this->ConvertToOutputForExisting(ruleFileName.c_str()).c_str()
<< "\n";
}
+
+ // Write jump-and-build rules that were recorded in the map.
+ this->WriteJumpAndBuildRules(makefileStream);
}
//----------------------------------------------------------------------------
@@ -586,6 +583,21 @@ cmLocalUnixMakefileGenerator2
{
depends.push_back(*obj);
}
+
+ // Add dependencies on libraries that will be linked.
+ std::set<cmStdString> emitted;
+ emitted.insert(target.GetName());
+ const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
+ for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
+ lib != tlibs.end(); ++lib)
+ {
+ // Don't emit the same library twice for this target.
+ if(emitted.insert(lib->first).second)
+ {
+ // Add this dependency.
+ this->AppendLibDepend(depends, lib->first.c_str());
+ }
+ }
depends.push_back(ruleFileName);
// Construct the full path to the executable that will be generated.
@@ -1088,6 +1100,157 @@ void cmLocalUnixMakefileGenerator2::AppendFlags(std::string& flags,
}
//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
+::AppendLibDepend(std::vector<std::string>& depends, const char* name)
+{
+ // There are a few cases for the name of the target:
+ // - CMake target in this directory: depend on it.
+ // - CMake target in another directory: depend and add jump-and-build.
+ // - Full path to an outside file: depend on it.
+ // - Other format (like -lm): do nothing.
+
+ // If it is a CMake target there will be a definition for it.
+ std::string dirVar = name;
+ dirVar += "_CMAKE_PATH";
+ const char* dir = m_Makefile->GetDefinition(dirVar.c_str());
+ if(dir && *dir)
+ {
+ // This is a CMake target somewhere in this project.
+ bool jumpAndBuild = false;
+
+ // Get the path to the library.
+ std::string libPath;
+ if(this->SamePath(m_Makefile->GetCurrentOutputDirectory(), dir))
+ {
+ // The target is in the current directory so this makefile will
+ // know about it already.
+ libPath = m_LibraryOutputPath;
+ }
+ else
+ {
+ // The target is in another directory. Get the path to it.
+ if(m_LibraryOutputPath.size())
+ {
+ libPath = m_LibraryOutputPath;
+ }
+ else
+ {
+ libPath = dir;
+ libPath += "/";
+ }
+
+ // We need to add a jump-and-build rule for this library.
+ jumpAndBuild = true;
+ }
+
+ // Add the name of the library's file. This depends on the type
+ // of the library.
+ std::string typeVar = name;
+ typeVar += "_LIBRARY_TYPE";
+ std::string libType = m_Makefile->GetSafeDefinition(typeVar.c_str());
+ std::string prefix;
+ std::string suffix;
+ if(libType == "SHARED")
+ {
+ prefix = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_PREFIX");
+ suffix = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX");
+ }
+ else if(libType == "MODULE")
+ {
+ prefix = m_Makefile->GetSafeDefinition("CMAKE_SHARED_MODULE_PREFIX");
+ suffix = m_Makefile->GetSafeDefinition("CMAKE_SHARED_MODULE_SUFFIX");
+ }
+ else if(libType == "STATIC")
+ {
+ prefix = m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX");
+ suffix = m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
+ }
+ libPath += prefix;
+ libPath += name;
+ libPath += suffix;
+
+ if(jumpAndBuild)
+ {
+ // We need to add a jump-and-build rule for this library.
+ cmLocalUnixMakefileGenerator2::RemoteTarget rt;
+ rt.m_BuildDirectory = dir;
+ rt.m_FilePath =libPath;
+ m_JumpAndBuild[name] = rt;
+ }
+
+ // Add a dependency on the library.
+ depends.push_back(this->ConvertToRelativeOutputPath(libPath.c_str()));
+ }
+ else
+ {
+ // This is not a CMake target. If it exists and is a full path we
+ // can depend on it.
+ if(cmSystemTools::FileExists(name) && cmSystemTools::FileIsFullPath(name))
+ {
+ depends.push_back(this->ConvertToRelativeOutputPath(name));
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
+::AppendRecursiveMake(std::string& cmd, const char* file, const char* tgt)
+{
+ // Call make on the given file.
+ cmd += "$(MAKE) -f ";
+ cmd += file;
+
+ // Pass down verbosity level.
+ cmd += " $(MAKESILENT) ";
+
+ // Most unix makes will pass the command line flags to make down to
+ // sub-invoked makes via an environment variable. However, some
+ // makes do not support that, so you have to pass the flags
+ // explicitly.
+ if(m_PassMakeflags)
+ {
+ cmd += "-$(MAKEFLAGS) ";
+ }
+
+ // Add the target.
+ cmd += tgt;
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
+::WriteJumpAndBuildRules(std::ostream& makefileStream)
+{
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+ commands.push_back("");
+ for(std::map<cmStdString, RemoteTarget>::iterator
+ jump = m_JumpAndBuild.begin(); jump != m_JumpAndBuild.end(); ++jump)
+ {
+ const cmLocalUnixMakefileGenerator2::RemoteTarget& rt = jump->second;
+ std::string& cmd = commands[0];
+ if(m_WindowsShell)
+ {
+ // TODO: implement windows version.
+ cmd = "";
+ }
+ else
+ {
+ cmd = "cd ";
+ cmd += this->ConvertToOutputForExisting(rt.m_BuildDirectory.c_str());
+ cmd += "; ";
+ std::string tgt = jump->first;
+ tgt += ".requires";
+ this->AppendRecursiveMake(cmd, "Makefile2", tgt.c_str());
+ }
+ this->OutputMakeRule(makefileStream, "jump rule for",
+ rt.m_FilePath.c_str(), depends, commands);
+ }
+}
+
+//----------------------------------------------------------------------------
bool
cmLocalUnixMakefileGenerator2
::ScanDependencies(std::vector<std::string> const& args)