ENH: Proper dependencies between shared libraries now exist in the generated makefiles. If a shared library links to another, the other will be built before the link is attempted.
This commit is contained in:
parent
94337f8015
commit
82996a636e
@ -229,7 +229,7 @@ void cmUnixMakefileGenerator::OutputMakefile(const char* file)
|
|||||||
this->OutputMakeVariables(fout);
|
this->OutputMakeVariables(fout);
|
||||||
this->OutputMakeFlags(fout);
|
this->OutputMakeFlags(fout);
|
||||||
this->OutputTargetRules(fout);
|
this->OutputTargetRules(fout);
|
||||||
this->OutputDependencies(fout);
|
this->OutputDependLibs(fout);
|
||||||
this->OutputTargets(fout);
|
this->OutputTargets(fout);
|
||||||
this->OutputSubDirectoryRules(fout);
|
this->OutputSubDirectoryRules(fout);
|
||||||
std::string dependName = m_Makefile->GetStartOutputDirectory();
|
std::string dependName = m_Makefile->GetStartOutputDirectory();
|
||||||
@ -339,7 +339,7 @@ void cmUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
|
|||||||
fout << "${" << l->first << "_SRC_OBJS} ";
|
fout << "${" << l->first << "_SRC_OBJS} ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fout << "\n";
|
fout << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -534,7 +534,7 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
|
|||||||
fout << "# rules for a shared library\n";
|
fout << "# rules for a shared library\n";
|
||||||
fout << "#\n";
|
fout << "#\n";
|
||||||
fout << m_LibraryOutputPath << "lib" << l->first << "$(SHLIB_SUFFIX): ${" <<
|
fout << m_LibraryOutputPath << "lib" << l->first << "$(SHLIB_SUFFIX): ${" <<
|
||||||
l->first << "_SRC_OBJS} \n";
|
l->first << "_SRC_OBJS} ${" << l->first << "_DEPEND_LIBS} \n";
|
||||||
fout << "\trm -f lib" << l->first << "$(SHLIB_SUFFIX)\n";
|
fout << "\trm -f lib" << l->first << "$(SHLIB_SUFFIX)\n";
|
||||||
fout << "\t$(CMAKE_CXX_COMPILER) ${CMAKE_SHLIB_LINK_FLAGS} "
|
fout << "\t$(CMAKE_CXX_COMPILER) ${CMAKE_SHLIB_LINK_FLAGS} "
|
||||||
"${CMAKE_SHLIB_BUILD_FLAGS} ${CMAKE_CXXFLAGS} -o \\\n";
|
"${CMAKE_SHLIB_BUILD_FLAGS} ${CMAKE_CXXFLAGS} -o \\\n";
|
||||||
@ -550,7 +550,7 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
|
|||||||
fout << "# rules for a shared module library\n";
|
fout << "# rules for a shared module library\n";
|
||||||
fout << "#\n";
|
fout << "#\n";
|
||||||
fout << m_LibraryOutputPath << "lib" << l->first << "$(MODULE_SUFFIX): ${" <<
|
fout << m_LibraryOutputPath << "lib" << l->first << "$(MODULE_SUFFIX): ${" <<
|
||||||
l->first << "_SRC_OBJS} \n";
|
l->first << "_SRC_OBJS} ${" << l->first << "_DEPEND_LIBS} \n";
|
||||||
fout << "\trm -f lib" << l->first << "$(MODULE_SUFFIX)\n";
|
fout << "\trm -f lib" << l->first << "$(MODULE_SUFFIX)\n";
|
||||||
fout << "\t$(CMAKE_CXX_COMPILER) ${CMAKE_MODULE_LINK_FLAGS} "
|
fout << "\t$(CMAKE_CXX_COMPILER) ${CMAKE_MODULE_LINK_FLAGS} "
|
||||||
"${CMAKE_MODULE_BUILD_FLAGS} ${CMAKE_CXXFLAGS} -o \\\n";
|
"${CMAKE_MODULE_BUILD_FLAGS} ${CMAKE_CXXFLAGS} -o \\\n";
|
||||||
@ -564,7 +564,7 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
|
|||||||
|| (l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
|
|| (l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
|
||||||
{
|
{
|
||||||
fout << m_ExecutableOutputPath << l->first << ": ${" <<
|
fout << m_ExecutableOutputPath << l->first << ": ${" <<
|
||||||
l->first << "_SRC_OBJS} ${CMAKE_DEPEND_LIBS}\n";
|
l->first << "_SRC_OBJS} ${" << l->first << "_DEPEND_LIBS}\n";
|
||||||
fout << "\t${CMAKE_CXX_COMPILER} ${CMAKE_SHLIB_LINK_FLAGS} ${CMAKE_CXXFLAGS} "
|
fout << "\t${CMAKE_CXX_COMPILER} ${CMAKE_SHLIB_LINK_FLAGS} ${CMAKE_CXXFLAGS} "
|
||||||
<< "${" << l->first << "_SRC_OBJS} ";
|
<< "${" << l->first << "_SRC_OBJS} ";
|
||||||
this->OutputLinkLibraries(fout, NULL,l->second);
|
this->OutputLinkLibraries(fout, NULL,l->second);
|
||||||
@ -574,93 +574,90 @@ void cmUnixMakefileGenerator::OutputTargets(std::ostream& fout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// output the list of libraries that the executables
|
// For each target that is an executable or shared library, generate
|
||||||
// in this makefile will depend on.
|
// the "<name>_DEPEND_LIBS" variable listing its library dependencies.
|
||||||
void cmUnixMakefileGenerator::OutputDependencies(std::ostream& fout)
|
void cmUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
|
||||||
{
|
{
|
||||||
// Each dependency should only be emitted once.
|
// Build a set of libraries that will be linked into any target in
|
||||||
std::set<std::string> emitted;
|
// this directory.
|
||||||
|
std::set<std::string> used;
|
||||||
fout << "CMAKE_DEPEND_LIBS = ";
|
|
||||||
cmTarget::LinkLibraries& libs = m_Makefile->GetLinkLibraries();
|
// for each target
|
||||||
cmTarget::LinkLibraries::const_iterator lib2;
|
const cmTargets &tgts = m_Makefile->GetTargets();
|
||||||
// Search the list of libraries that will be linked into
|
for(cmTargets::const_iterator l = tgts.begin();
|
||||||
// the executable
|
l != tgts.end(); l++)
|
||||||
emitted.clear();
|
|
||||||
for(lib2 = libs.begin(); lib2 != libs.end(); ++lib2)
|
|
||||||
{
|
{
|
||||||
if( ! emitted.insert(lib2->first).second ) continue;
|
// Each dependency should only be emitted once per target.
|
||||||
|
std::set<std::string> emitted;
|
||||||
const char* cacheValue
|
if ((l->second.GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
= m_Makefile->GetDefinition(lib2->first.c_str());
|
|| (l->second.GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
if(cacheValue )
|
|| (l->second.GetType() == cmTarget::EXECUTABLE)
|
||||||
|
|| (l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
|
||||||
{
|
{
|
||||||
// if there is a cache value then this is a library that cmake
|
fout << l->first << "_DEPEND_LIBS = ";
|
||||||
// knows how to build, so we can depend on it
|
|
||||||
std::string libpath;
|
// A library should not depend on itself!
|
||||||
if (strcmp(m_Makefile->GetCurrentOutputDirectory(), cacheValue) != 0)
|
emitted.insert(l->first);
|
||||||
|
|
||||||
|
// First look at all makefile level link libraries.
|
||||||
|
const cmTarget::LinkLibraries& libs = m_Makefile->GetLinkLibraries();
|
||||||
|
for(cmTarget::LinkLibraries::const_iterator lib = libs.begin();
|
||||||
|
lib != libs.end(); ++lib)
|
||||||
{
|
{
|
||||||
// if the library is not in the current directory, then get the full
|
// Record that this library was used.
|
||||||
// path to it
|
used.insert(lib->first);
|
||||||
libpath = cacheValue;
|
|
||||||
if(m_LibraryOutputPath.size())
|
// Don't emit the same library twice for this target.
|
||||||
|
if(emitted.insert(lib->first).second)
|
||||||
{
|
{
|
||||||
libpath = m_LibraryOutputPath;
|
// Output this dependency.
|
||||||
libpath += "lib";
|
this->OutputLibDepend(fout, lib->first.c_str());
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
libpath += "/lib";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Now, look at all link libraries specific to this target.
|
||||||
|
const cmTarget::LinkLibraries& tlibs = l->second.GetLinkLibraries();
|
||||||
|
for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
|
||||||
|
lib != tlibs.end(); ++lib)
|
||||||
{
|
{
|
||||||
// library is in current Makefile so use lib as a prefix
|
// Record that this library was used.
|
||||||
libpath = m_LibraryOutputPath;
|
used.insert(lib->first);
|
||||||
libpath += "lib";
|
|
||||||
|
// Don't emit the same library twice for this target.
|
||||||
|
if(emitted.insert(lib->first).second)
|
||||||
|
{
|
||||||
|
// Output this dependency.
|
||||||
|
this->OutputLibDepend(fout, lib->first.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// add the library name
|
|
||||||
libpath += lib2->first;
|
fout << "\n";
|
||||||
// add the correct extension
|
|
||||||
std::string ltname = lib2->first+"_LIBRARY_TYPE";
|
|
||||||
const char* libType
|
|
||||||
= m_Makefile->GetDefinition(ltname.c_str());
|
|
||||||
if(libType && std::string(libType) == "SHARED")
|
|
||||||
{
|
|
||||||
libpath += m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
|
|
||||||
}
|
|
||||||
else if (libType && std::string(libType) == "MODULE")
|
|
||||||
{
|
|
||||||
libpath += m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
libpath += ".a";
|
|
||||||
}
|
|
||||||
fout << libpath << " ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fout << "\n\n";
|
|
||||||
emitted.clear();
|
fout << "\n";
|
||||||
for(lib2 = libs.begin(); lib2 != libs.end(); ++lib2)
|
|
||||||
|
// Loop over the libraries used and make sure there is a rule to
|
||||||
|
// build them in this makefile. If the library is in another
|
||||||
|
// directory, add a rule to jump to that directory and make sure it
|
||||||
|
// exists.
|
||||||
|
for(std::set<std::string>::const_iterator lib = used.begin();
|
||||||
|
lib != used.end(); ++lib)
|
||||||
{
|
{
|
||||||
// loop over the list of directories that the libraries might
|
// loop over the list of directories that the libraries might
|
||||||
// be in, looking for an ADD_LIBRARY(lib...) line. This would
|
// be in, looking for an ADD_LIBRARY(lib...) line. This would
|
||||||
// be stored in the cache
|
// be stored in the cache
|
||||||
if( ! emitted.insert(lib2->first).second ) continue;
|
const char* cacheValue = m_Makefile->GetDefinition(lib->c_str());
|
||||||
|
|
||||||
const char* cacheValue
|
|
||||||
= m_Makefile->GetDefinition(lib2->first.c_str());
|
|
||||||
// if cache and not the current directory add a rule, to
|
// if cache and not the current directory add a rule, to
|
||||||
// jump into the directory and build for the first time
|
// jump into the directory and build for the first time
|
||||||
if(cacheValue
|
if(cacheValue
|
||||||
&& (strcmp(m_Makefile->GetCurrentOutputDirectory(), cacheValue) != 0))
|
&& (strcmp(m_Makefile->GetCurrentOutputDirectory(), cacheValue) != 0))
|
||||||
{
|
{
|
||||||
std::string library = "lib";
|
std::string library = "lib";
|
||||||
library += lib2->first;
|
library += *lib;
|
||||||
std::string libpath = cacheValue;
|
std::string libpath = cacheValue;
|
||||||
// add the correct extension
|
// add the correct extension
|
||||||
std::string ltname = lib2->first+"_LIBRARY_TYPE";
|
std::string ltname = *lib+"_LIBRARY_TYPE";
|
||||||
const char* libType
|
const char* libType
|
||||||
= m_Makefile->GetDefinition(ltname.c_str());
|
= m_Makefile->GetDefinition(ltname.c_str());
|
||||||
if(libType && std::string(libType) == "SHARED")
|
if(libType && std::string(libType) == "SHARED")
|
||||||
@ -692,6 +689,58 @@ void cmUnixMakefileGenerator::OutputDependencies(std::ostream& fout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmUnixMakefileGenerator::OutputLibDepend(std::ostream& fout,
|
||||||
|
const char* name)
|
||||||
|
{
|
||||||
|
const char* cacheValue = m_Makefile->GetDefinition(name);
|
||||||
|
if(cacheValue )
|
||||||
|
{
|
||||||
|
// if there is a cache value, then this is a library that cmake
|
||||||
|
// knows how to build, so we can depend on it
|
||||||
|
std::string libpath;
|
||||||
|
if (strcmp(m_Makefile->GetCurrentOutputDirectory(), cacheValue) != 0)
|
||||||
|
{
|
||||||
|
// if the library is not in the current directory, then get the full
|
||||||
|
// path to it
|
||||||
|
libpath = cacheValue;
|
||||||
|
if(m_LibraryOutputPath.size())
|
||||||
|
{
|
||||||
|
libpath = m_LibraryOutputPath;
|
||||||
|
libpath += "lib";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
libpath += "/lib";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// library is in current Makefile so use lib as a prefix
|
||||||
|
libpath = m_LibraryOutputPath;
|
||||||
|
libpath += "lib";
|
||||||
|
}
|
||||||
|
// add the library name
|
||||||
|
libpath += name;
|
||||||
|
// add the correct extension
|
||||||
|
std::string ltname = name;
|
||||||
|
ltname += "_LIBRARY_TYPE";
|
||||||
|
const char* libType = m_Makefile->GetDefinition(ltname.c_str());
|
||||||
|
if(libType && std::string(libType) == "SHARED")
|
||||||
|
{
|
||||||
|
libpath += m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
|
||||||
|
}
|
||||||
|
else if (libType && std::string(libType) == "MODULE")
|
||||||
|
{
|
||||||
|
libpath += m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
libpath += ".a";
|
||||||
|
}
|
||||||
|
fout << libpath << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// output make include flags
|
// output make include flags
|
||||||
void cmUnixMakefileGenerator::OutputMakeFlags(std::ostream& fout)
|
void cmUnixMakefileGenerator::OutputMakeFlags(std::ostream& fout)
|
||||||
|
@ -101,7 +101,8 @@ private:
|
|||||||
void OutputTargets(std::ostream&);
|
void OutputTargets(std::ostream&);
|
||||||
void OutputSubDirectoryRules(std::ostream&);
|
void OutputSubDirectoryRules(std::ostream&);
|
||||||
void OutputDependInformation(std::ostream&);
|
void OutputDependInformation(std::ostream&);
|
||||||
void OutputDependencies(std::ostream&);
|
void OutputDependLibs(std::ostream&);
|
||||||
|
void OutputLibDepend(std::ostream&, const char*);
|
||||||
void OutputCustomRules(std::ostream&);
|
void OutputCustomRules(std::ostream&);
|
||||||
void OutputMakeVariables(std::ostream&);
|
void OutputMakeVariables(std::ostream&);
|
||||||
void OutputMakeRules(std::ostream&);
|
void OutputMakeRules(std::ostream&);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user