ENH: Added executable dependencies on libraries including jump-and-build support.
This commit is contained in:
parent
235bf2547c
commit
8e0985f9f1
|
@ -91,17 +91,11 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
|
||||||
runRule += " --check-rerun ";
|
runRule += " --check-rerun ";
|
||||||
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
|
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
|
||||||
|
|
||||||
// Most unix makes will pass the command line flags to make down to
|
// Construct recursive calls for the "all" rules.
|
||||||
// sub-invoked makes via an environment variable. However, some
|
std::string depRule;
|
||||||
// makes do not support that, so you have to pass the flags
|
std::string allRule;
|
||||||
// explicitly.
|
this->AppendRecursiveMake(depRule, "Makefile2", "all.depends");
|
||||||
const char* depRule = "$(MAKE) -f Makefile2 $(MAKESILENT) all.depends";
|
this->AppendRecursiveMake(allRule, "Makefile2", "all");
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the main entry point target. This must be the VERY first
|
// 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.
|
||||||
|
@ -179,6 +173,9 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
|
||||||
<< this->ConvertToOutputForExisting(ruleFileName.c_str()).c_str()
|
<< this->ConvertToOutputForExisting(ruleFileName.c_str()).c_str()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write jump-and-build rules that were recorded in the map.
|
||||||
|
this->WriteJumpAndBuildRules(makefileStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -586,6 +583,21 @@ cmLocalUnixMakefileGenerator2
|
||||||
{
|
{
|
||||||
depends.push_back(*obj);
|
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);
|
depends.push_back(ruleFileName);
|
||||||
|
|
||||||
// Construct the full path to the executable that will be generated.
|
// Construct the full path to the executable that will be generated.
|
||||||
|
@ -1087,6 +1099,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
|
bool
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
|
|
|
@ -90,10 +90,21 @@ protected:
|
||||||
void AddSharedFlags(std::string& flags, const char* lang, bool shared);
|
void AddSharedFlags(std::string& flags, const char* lang, bool shared);
|
||||||
void AddConfigVariableFlags(std::string& flags, const char* var);
|
void AddConfigVariableFlags(std::string& flags, const char* var);
|
||||||
void AppendFlags(std::string& flags, const char* newFlags);
|
void AppendFlags(std::string& flags, const char* newFlags);
|
||||||
|
void AppendLibDepend(std::vector<std::string>& depends, const char* name);
|
||||||
|
void AppendRecursiveMake(std::string& cmd, const char* file, const char* tgt);
|
||||||
|
void WriteJumpAndBuildRules(std::ostream& makefileStream);
|
||||||
|
|
||||||
static bool ScanDependenciesC(const char* objFile, const char* srcFile,
|
static bool ScanDependenciesC(const char* objFile, const char* srcFile,
|
||||||
std::vector<std::string> const& includes);
|
std::vector<std::string> const& includes);
|
||||||
private:
|
private:
|
||||||
|
// Map from target name to build directory containing it for
|
||||||
|
// jump-and-build targets.
|
||||||
|
struct RemoteTarget
|
||||||
|
{
|
||||||
|
std::string m_BuildDirectory;
|
||||||
|
std::string m_FilePath;
|
||||||
|
};
|
||||||
|
std::map<cmStdString, RemoteTarget> m_JumpAndBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue