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:
Brad King 2005-04-22 16:11:00 -04:00
parent 1b71f4477b
commit b1c5289787
4 changed files with 165 additions and 72 deletions

View File

@ -1857,9 +1857,9 @@ cmLocalUnixMakefileGenerator2
std::string targetNameSO;
std::string targetNameReal;
std::string targetNameBase;
this->GetLibraryNames(target,
targetName, targetNameSO,
targetNameReal, targetNameBase);
target.GetLibraryNames(m_Makefile,
targetName, targetNameSO,
targetNameReal, targetNameBase);
// Construct the full path version of the names.
std::string outpath = m_LibraryOutputPath;
@ -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)
{
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(targetFullPathSO);
cleanFiles.push_back(cleanFullSharedRealName);
}
if(targetOutPath != targetOutPathSO &&
targetOutPath != targetOutPathReal)
if(cleanSharedSOName != cleanStaticName &&
cleanSharedSOName != cleanSharedRealName)
{
cleanFiles.push_back(targetFullPath);
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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;