ENH: Created cmTarget::GetLibraryNames to replace cmLocalUnixMakefileGenerator2::GetLibraryNames. Added cmTarget::GetLibraryCleanNames to be used by cmLocalUnixMakefileGenerator2. Now when a library is linked both the shared and static versions are removed from the build tree. In this way we avoid having both kinds of libraries present when the user switches BUILD_SHARED_LIBS on/off. This prevents problems with turning off shared libraries and then expecting the linker to use the static libraries only to find it is using the out-of-date shared versions.
This commit is contained in:
parent
1b71f4477b
commit
b1c5289787
|
@ -1857,7 +1857,7 @@ cmLocalUnixMakefileGenerator2
|
|||
std::string targetNameSO;
|
||||
std::string targetNameReal;
|
||||
std::string targetNameBase;
|
||||
this->GetLibraryNames(target,
|
||||
target.GetLibraryNames(m_Makefile,
|
||||
targetName, targetNameSO,
|
||||
targetNameReal, targetNameBase);
|
||||
|
||||
|
@ -1897,18 +1897,42 @@ cmLocalUnixMakefileGenerator2
|
|||
buildEcho += targetOutPath.c_str();
|
||||
this->AppendEcho(commands, buildEcho.c_str());
|
||||
|
||||
// Add a command to remove any existing files for this library.
|
||||
// Construct a list of files associated with this library that may
|
||||
// need to be cleaned.
|
||||
std::vector<std::string> cleanFiles;
|
||||
cleanFiles.push_back(targetFullPathReal);
|
||||
if(targetOutPathSO != targetOutPathReal)
|
||||
{
|
||||
cleanFiles.push_back(targetFullPathSO);
|
||||
}
|
||||
if(targetOutPath != targetOutPathSO &&
|
||||
targetOutPath != targetOutPathReal)
|
||||
std::string cleanStaticName;
|
||||
std::string cleanSharedName;
|
||||
std::string cleanSharedSOName;
|
||||
std::string cleanSharedRealName;
|
||||
target.GetLibraryCleanNames(m_Makefile,
|
||||
cleanStaticName,
|
||||
cleanSharedName,
|
||||
cleanSharedSOName,
|
||||
cleanSharedRealName);
|
||||
std::string cleanFullStaticName = outpath + cleanStaticName;
|
||||
std::string cleanFullSharedName = outpath + cleanSharedName;
|
||||
std::string cleanFullSharedSOName = outpath + cleanSharedSOName;
|
||||
std::string cleanFullSharedRealName = outpath + cleanSharedRealName;
|
||||
cleanFiles.push_back(cleanFullStaticName);
|
||||
if(cleanSharedRealName != cleanStaticName)
|
||||
{
|
||||
cleanFiles.push_back(targetFullPath);
|
||||
cleanFiles.push_back(cleanFullSharedRealName);
|
||||
}
|
||||
if(cleanSharedSOName != cleanStaticName &&
|
||||
cleanSharedSOName != cleanSharedRealName)
|
||||
{
|
||||
cleanFiles.push_back(cleanFullSharedSOName);
|
||||
}
|
||||
if(cleanSharedName != cleanStaticName &&
|
||||
cleanSharedName != cleanSharedSOName &&
|
||||
cleanSharedName != cleanSharedRealName)
|
||||
{
|
||||
cleanFiles.push_back(cleanFullSharedName);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a command to remove any existing files for this library.
|
||||
this->AppendCleanCommand(commands, cleanFiles);
|
||||
|
||||
// Add the pre-build and pre-link rules.
|
||||
|
@ -2775,60 +2799,6 @@ cmLocalUnixMakefileGenerator2::SamePath(const char* path1, const char* path2)
|
|||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalUnixMakefileGenerator2::GetLibraryNames(const cmTarget& t,
|
||||
std::string& name,
|
||||
std::string& soName,
|
||||
std::string& realName,
|
||||
std::string& baseName)
|
||||
{
|
||||
// Check for library version properties.
|
||||
const char* version = t.GetProperty("VERSION");
|
||||
const char* soversion = t.GetProperty("SOVERSION");
|
||||
if((t.GetType() != cmTarget::SHARED_LIBRARY &&
|
||||
t.GetType() != cmTarget::MODULE_LIBRARY) ||
|
||||
!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
|
||||
{
|
||||
// Versioning is supported only for shared libraries and modules,
|
||||
// and then only when the platform supports an soname flag.
|
||||
version = 0;
|
||||
soversion = 0;
|
||||
}
|
||||
if(version && !soversion)
|
||||
{
|
||||
// The soversion must be set if the library version is set. Use
|
||||
// the library version as the soversion.
|
||||
soversion = version;
|
||||
}
|
||||
|
||||
// The library name.
|
||||
name = t.GetFullName(m_Makefile);
|
||||
|
||||
// The library's soname.
|
||||
soName = name;
|
||||
if(soversion)
|
||||
{
|
||||
soName += ".";
|
||||
soName += soversion;
|
||||
}
|
||||
|
||||
// The library's real name on disk.
|
||||
realName = name;
|
||||
if(version)
|
||||
{
|
||||
realName += ".";
|
||||
realName += version;
|
||||
}
|
||||
else if(soversion)
|
||||
{
|
||||
realName += ".";
|
||||
realName += soversion;
|
||||
}
|
||||
|
||||
// The library name without extension.
|
||||
baseName = t.GetBaseName(m_Makefile);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmLocalUnixMakefileGenerator2
|
||||
|
|
|
@ -221,9 +221,6 @@ protected:
|
|||
|
||||
//==========================================================================
|
||||
bool SamePath(const char* path1, const char* path2);
|
||||
void GetLibraryNames(const cmTarget& t,
|
||||
std::string& name, std::string& soName,
|
||||
std::string& realName, std::string& baseName);
|
||||
std::string ConvertToMakeTarget(const char* tgt);
|
||||
std::string& CreateSafeUniqueObjectFileName(const char* sin);
|
||||
std::string CreateMakeVariable(const char* sin, const char* s2in);
|
||||
|
|
|
@ -974,3 +974,108 @@ cmTarget::GetBaseNameInternal(cmMakefile* mf, TargetType type) const
|
|||
name += this->GetName();
|
||||
return name;
|
||||
}
|
||||
|
||||
void cmTarget::GetLibraryNames(cmMakefile* mf,
|
||||
std::string& name,
|
||||
std::string& soName,
|
||||
std::string& realName,
|
||||
std::string& baseName) const
|
||||
{
|
||||
// Get the names based on the real type of the library.
|
||||
this->GetLibraryNamesInternal(mf, name, soName, realName, this->GetType());
|
||||
|
||||
// The library name without extension.
|
||||
baseName = this->GetBaseName(mf);
|
||||
}
|
||||
|
||||
void cmTarget::GetLibraryCleanNames(cmMakefile* mf,
|
||||
std::string& staticName,
|
||||
std::string& sharedName,
|
||||
std::string& sharedSOName,
|
||||
std::string& sharedRealName) const
|
||||
{
|
||||
// Get the name as if this were a static library.
|
||||
std::string soName;
|
||||
std::string realName;
|
||||
this->GetLibraryNamesInternal(mf, staticName, soName, realName,
|
||||
cmTarget::STATIC_LIBRARY);
|
||||
|
||||
// Get the names as if this were a shared library.
|
||||
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
{
|
||||
// Since the real type is static then the user either specified
|
||||
// STATIC or did not specify a type. In the former case the
|
||||
// shared library will never be present. In the latter case the
|
||||
// type will never be MODULE. Either way the only names that
|
||||
// might have to be cleaned are the shared library names.
|
||||
this->GetLibraryNamesInternal(mf, sharedName, sharedSOName,
|
||||
sharedRealName, cmTarget::SHARED_LIBRARY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the name of the real type of the library (shared or module).
|
||||
this->GetLibraryNamesInternal(mf, sharedName, sharedSOName,
|
||||
sharedRealName, this->GetType());
|
||||
}
|
||||
}
|
||||
|
||||
void cmTarget::GetLibraryNamesInternal(cmMakefile* mf,
|
||||
std::string& name,
|
||||
std::string& soName,
|
||||
std::string& realName,
|
||||
TargetType type) const
|
||||
{
|
||||
// Construct the name of the soname flag variable for this language.
|
||||
const char* ll =
|
||||
this->GetLinkerLanguage(
|
||||
mf->GetLocalGenerator()->GetGlobalGenerator());
|
||||
std::string sonameFlag = "CMAKE_SHARED_LIBRARY_SONAME";
|
||||
if(ll)
|
||||
{
|
||||
sonameFlag += "_";
|
||||
sonameFlag += ll;
|
||||
}
|
||||
sonameFlag += "_FLAG";
|
||||
|
||||
// Check for library version properties.
|
||||
const char* version = this->GetProperty("VERSION");
|
||||
const char* soversion = this->GetProperty("SOVERSION");
|
||||
if((type != cmTarget::SHARED_LIBRARY && type != cmTarget::MODULE_LIBRARY) ||
|
||||
!mf->GetDefinition(sonameFlag.c_str()))
|
||||
{
|
||||
// Versioning is supported only for shared libraries and modules,
|
||||
// and then only when the platform supports an soname flag.
|
||||
version = 0;
|
||||
soversion = 0;
|
||||
}
|
||||
if(version && !soversion)
|
||||
{
|
||||
// The soversion must be set if the library version is set. Use
|
||||
// the library version as the soversion.
|
||||
soversion = version;
|
||||
}
|
||||
|
||||
// The library name.
|
||||
name = this->GetFullNameInternal(mf, type);
|
||||
|
||||
// The library's soname.
|
||||
soName = name;
|
||||
if(soversion)
|
||||
{
|
||||
soName += ".";
|
||||
soName += soversion;
|
||||
}
|
||||
|
||||
// The library's real name on disk.
|
||||
realName = name;
|
||||
if(version)
|
||||
{
|
||||
realName += ".";
|
||||
realName += version;
|
||||
}
|
||||
else if(soversion)
|
||||
{
|
||||
realName += ".";
|
||||
realName += soversion;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,13 +168,30 @@ public:
|
|||
///! Return the name of the variable to look up the target suffix
|
||||
const char* GetPrefixVariable() const;
|
||||
|
||||
// Get the full name of the target according to the settings in the
|
||||
// given makefile.
|
||||
/** Get the full name of the target according to the settings in the
|
||||
given makefile. */
|
||||
std::string GetFullName(cmMakefile* mf) const;
|
||||
|
||||
// Get the baes name (no suffix) of the target according to the
|
||||
// settings in the given makefile.
|
||||
/** Get the base name (no suffix) of the target according to the
|
||||
settings in the given makefile. */
|
||||
std::string GetBaseName(cmMakefile* mf) const;
|
||||
|
||||
/** Get the names of the library needed to generate a build rule
|
||||
that takes into account shared library version numbers. This
|
||||
should be called only on a library target. */
|
||||
void GetLibraryNames(cmMakefile* mf, std::string& name,
|
||||
std::string& soName, std::string& realName,
|
||||
std::string& baseName) const;
|
||||
|
||||
/** Get the names of the library used to remove existing copies of
|
||||
the library from the build tree either before linking or during
|
||||
a clean step. This should be called only on a library
|
||||
target. */
|
||||
void GetLibraryCleanNames(cmMakefile* mf,
|
||||
std::string& staticName,
|
||||
std::string& sharedName,
|
||||
std::string& sharedSOName,
|
||||
std::string& sharedRealName) const;
|
||||
private:
|
||||
/**
|
||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||
|
@ -233,7 +250,11 @@ private:
|
|||
const char* GetPrefixVariableInternal(TargetType type) const;
|
||||
std::string GetFullNameInternal(cmMakefile* mf, TargetType type) const;
|
||||
std::string GetBaseNameInternal(cmMakefile* mf, TargetType type) const;
|
||||
|
||||
void GetLibraryNamesInternal(cmMakefile* mf,
|
||||
std::string& name,
|
||||
std::string& soName,
|
||||
std::string& realName,
|
||||
TargetType type) const;
|
||||
private:
|
||||
std::string m_Name;
|
||||
std::vector<cmCustomCommand> m_PreBuildCommands;
|
||||
|
|
Loading…
Reference in New Issue