summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx310
1 files changed, 209 insertions, 101 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3480794..c5471b8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -24,6 +24,13 @@
#include <queue>
#include <stdlib.h> // required for atof
+//----------------------------------------------------------------------------
+cmTarget::cmTarget()
+{
+ m_Makefile = 0;
+ m_LinkLibrariesAnalyzed = false;
+ m_LinkDirectoriesComputed = false;
+}
void cmTarget::SetType(TargetType type, const char* name)
{
@@ -171,9 +178,7 @@ void cmTarget::TraceVSDependencies(std::string projFile,
dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
}
// watch for target dependencies,
- std::string libPath = dep + "_CMAKE_PATH";
- const char* cacheValue = makefile->GetDefinition(libPath.c_str());
- if (cacheValue && *cacheValue)
+ if(m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, dep.c_str()))
{
// add the depend as a utility on the target
this->AddUtility(dep.c_str());
@@ -271,14 +276,71 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf,
m_PrevLinkedLibraries = libs;
}
+//----------------------------------------------------------------------------
void cmTarget::AddLinkDirectory(const char* d)
{
// Make sure we don't add unnecessary search directories.
- if( std::find( m_LinkDirectories.begin(), m_LinkDirectories.end(), d )
- == m_LinkDirectories.end() )
- m_LinkDirectories.push_back( d );
+ if(std::find(m_ExplicitLinkDirectories.begin(),
+ m_ExplicitLinkDirectories.end(), d)
+ == m_ExplicitLinkDirectories.end() )
+ {
+ m_ExplicitLinkDirectories.push_back( d );
+ m_LinkDirectoriesComputed = false;
+ }
}
+//----------------------------------------------------------------------------
+const std::vector<std::string>& cmTarget::GetLinkDirectories()
+{
+ // Make sure all library dependencies have been analyzed.
+ if(!m_LinkLibrariesAnalyzed && !m_LinkLibraries.empty())
+ {
+ cmSystemTools::Error(
+ "cmTarget::GetLinkDirectories called before cmTarget::AnalyzeLibDependencies on target ",
+ m_Name.c_str());
+ }
+
+ // Make sure the complete set of link directories has been computed.
+ if(!m_LinkDirectoriesComputed)
+ {
+ // Compute the full set of link directories including the
+ // locations of targets that have been linked in. Start with the
+ // link directories given explicitly.
+ m_LinkDirectories = m_ExplicitLinkDirectories;
+ for(LinkLibraries::iterator ll = m_LinkLibraries.begin();
+ ll != m_LinkLibraries.end(); ++ll)
+ {
+ // If this library is a CMake target then add its location as a
+ // link directory.
+ std::string lib = ll->first;
+ cmTarget* tgt = 0;
+ if(m_Makefile && m_Makefile->GetLocalGenerator() &&
+ m_Makefile->GetLocalGenerator()->GetGlobalGenerator())
+ {
+ tgt = (m_Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->FindTarget(0, lib.c_str()));
+ }
+ if(tgt)
+ {
+ // Add the directory only if it is not already present. This
+ // is an N^2 algorithm for adding the directories, but N
+ // should not get very big.
+ const char* libpath = tgt->GetDirectory();
+ if(std::find(m_LinkDirectories.begin(), m_LinkDirectories.end(),
+ libpath) == m_LinkDirectories.end())
+ {
+ m_LinkDirectories.push_back(libpath);
+ }
+ }
+ }
+
+ // The complete set of link directories has now been computed.
+ m_LinkDirectoriesComputed = true;
+ }
+
+ // Return the complete set of link directories.
+ return m_LinkDirectories;
+}
void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
{
@@ -498,11 +560,6 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// The dependency map.
DependencyMap dep_map;
- // If LIBRARY_OUTPUT_PATH is not set, then we must add search paths
- // for all the new libraries added by the dependency analysis.
- const char* libOutPath = mf.GetDefinition("LIBRARY_OUTPUT_PATH");
- bool addLibDirs = (libOutPath==0 || strcmp(libOutPath,"")==0);
-
// 1. Build the dependency graph
//
for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
@@ -541,30 +598,11 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
}
}
-
// 4. Add the new libraries to the link line.
//
for( std::vector<std::string>::reverse_iterator k = newLinkLibraries.rbegin();
k != newLinkLibraries.rend(); ++k )
{
- if( addLibDirs )
- {
- // who the hell knows what this is, I think that K contains the
- // name of a library but ... Ken
- // k contains the same stuff that are on the LINK_LIBRARIES
- // commands. Normally, they would just be library names. -- Amitha.
- std::string libPathStr = *k + "_CMAKE_PATH";
- const char* libpath = mf.GetDefinition( libPathStr.c_str() );
- if( libpath )
- {
- // Don't add a link directory that is already present.
- if(std::find(m_LinkDirectories.begin(),
- m_LinkDirectories.end(), libpath) == m_LinkDirectories.end())
- {
- m_LinkDirectories.push_back(libpath);
- }
- }
- }
std::string linkType = *k;
linkType += "_LINK_TYPE";
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
@@ -582,6 +620,7 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
}
m_LinkLibraries.push_back( std::make_pair(*k,llt) );
}
+ m_LinkLibrariesAnalyzed = true;
}
@@ -724,6 +763,45 @@ void cmTarget::SetProperty(const char* prop, const char* value)
m_Properties[prop] = value;
}
+const char* cmTarget::GetDirectory()
+{
+ switch( this->GetType() )
+ {
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ m_Directory = m_Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+ break;
+ case cmTarget::EXECUTABLE:
+ m_Directory = m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ break;
+ default:
+ return 0;
+ }
+ if(m_Directory.empty())
+ {
+ m_Directory = m_Makefile->GetStartOutputDirectory();
+ }
+ return m_Directory.c_str();
+}
+
+const char* cmTarget::GetLocation(const char* config)
+{
+ m_Location = this->GetDirectory();
+ if(!m_Location.empty())
+ {
+ m_Location += "/";
+ }
+ const char* cfgid = m_Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+ if(cfgid && strcmp(cfgid, ".") != 0)
+ {
+ m_Location += cfgid;
+ m_Location += "/";
+ }
+ m_Location += this->GetFullName(config);
+ return m_Location.c_str();
+}
+
void cmTarget::UpdateLocation()
{
// make sure we have a makefile
@@ -908,12 +986,12 @@ const char* cmTarget::GetCreateRuleVariable()
return "";
}
-const char* cmTarget::GetSuffixVariable()
+const char* cmTarget::GetSuffixVariable()
{
return this->GetSuffixVariableInternal(this->GetType());
}
-const char* cmTarget::GetSuffixVariableInternal(TargetType type)
+const char* cmTarget::GetSuffixVariableInternal(TargetType type)
{
switch(type)
{
@@ -958,15 +1036,81 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type)
return "";
}
-std::string cmTarget::GetFullName()
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullName(const char* config)
+{
+ return this->GetFullNameInternal(this->GetType(), config);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetFullName(std::string& prefix, std::string& base,
+ std::string& suffix, const char* config)
+{
+ this->GetFullNameInternal(this->GetType(), config, prefix, base, suffix);
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullPath(const char* config)
+{
+ // Start with the output directory for the target.
+ std::string fpath = this->GetDirectory();
+ fpath += "/";
+
+ // Add the configuration's subdirectory. This may need to be replaced with
+ // a call into the generator found through m_Makefile so that each
+ // generator can map configuration names to output directories its own way.
+ if(config)
+ {
+ fpath += config;
+ fpath += "/";
+ }
+
+ // Add the full name of the target.
+ fpath += this->GetFullName(config);
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullNameInternal(TargetType type, const char* config)
{
- return this->GetFullNameInternal(this->GetType());
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(type, config, prefix, base, suffix);
+ return prefix+base+suffix;
}
-std::string cmTarget::GetFullNameInternal(TargetType type)
+//----------------------------------------------------------------------------
+void cmTarget::GetFullNameInternal(TargetType type,
+ const char* config,
+ std::string& outPrefix,
+ std::string& outBase,
+ std::string& outSuffix)
{
+ // Use just the target name for non-main target types.
+ if(type != cmTarget::STATIC_LIBRARY &&
+ type != cmTarget::SHARED_LIBRARY &&
+ type != cmTarget::MODULE_LIBRARY &&
+ type != cmTarget::EXECUTABLE)
+ {
+ outPrefix = "";
+ outBase = this->GetName();
+ outSuffix = "";
+ return;
+ }
+
+ // Compute the full name for main target types.
const char* targetPrefix = this->GetProperty("PREFIX");
const char* targetSuffix = this->GetProperty("SUFFIX");
+ const char* configPostfix = 0;
+ if(config && *config && type != cmTarget::EXECUTABLE)
+ {
+ std::string configVar = "CMAKE_";
+ configVar += config;
+ configVar += "_POSTFIX";
+ configVar = cmSystemTools::UpperCase(configVar);
+ configPostfix = m_Makefile->GetDefinition(configVar.c_str());
+ }
const char* prefixVar = this->GetPrefixVariableInternal(type);
const char* suffixVar = this->GetSuffixVariableInternal(type);
const char* ll =
@@ -999,91 +1143,48 @@ std::string cmTarget::GetFullNameInternal(TargetType type)
}
// Begin the final name with the prefix.
- std::string name = targetPrefix?targetPrefix:"";
+ outPrefix = targetPrefix?targetPrefix:"";
// Append the target name or property-specified name. Support this
// only for executable targets.
const char* outname = this->GetProperty("OUTPUT_NAME");
if(outname && type == cmTarget::EXECUTABLE)
{
- name += outname;
+ outBase = outname;
}
else
{
- name += this->GetName();
+ outBase = this->GetName();
}
- // Append the suffix.
- name += targetSuffix?targetSuffix:"";
-
- // Return the final name.
- return name;
-}
-
-std::string cmTarget::GetBaseName()
-{
- return this->GetBaseNameInternal(this->GetType());
-}
+ // Append the per-configuration postfix.
+ outBase += configPostfix?configPostfix:"";
-std::string
-cmTarget::GetBaseNameInternal(TargetType type)
-{
- std::string pathPrefix = "";
-#ifdef __APPLE__
- if(this->GetPropertyAsBool("MACOSX_BUNDLE"))
- {
- pathPrefix = this->GetName();
- pathPrefix += ".app/Contents/MacOS/";
- }
-#endif
- const char* targetPrefix = this->GetProperty("PREFIX");
- const char* prefixVar = this->GetPrefixVariableInternal(type);
- // if there is no prefix on the target use the cmake definition
- if(!targetPrefix && prefixVar)
- {
- // first check for a language specific suffix var
- const char* ll =
- this->GetLinkerLanguage(
- m_Makefile->GetLocalGenerator()->GetGlobalGenerator());
- if(ll)
- {
- std::string langPrefix = prefixVar + std::string("_") + ll;
- targetPrefix = m_Makefile->GetDefinition(langPrefix.c_str());
- }
- // if there not a language specific suffix then use the general one
- if(!targetPrefix)
- {
- targetPrefix = m_Makefile->GetSafeDefinition(prefixVar);
- }
- }
- std::string name = pathPrefix;
- name += targetPrefix?targetPrefix:"";
- name += this->GetName();
- return name;
+ // Append the suffix.
+ outSuffix = targetSuffix?targetSuffix:"";
}
void cmTarget::GetLibraryNames(std::string& name,
std::string& soName,
std::string& realName,
- std::string& baseName)
+ const char* config)
{
// Get the names based on the real type of the library.
- this->GetLibraryNamesInternal(name, soName, realName, this->GetType());
-
- // The library name without extension.
- baseName = this->GetBaseName();
+ this->GetLibraryNamesInternal(name, soName, realName, this->GetType(),
+ config);
}
void cmTarget::GetLibraryCleanNames(std::string& staticName,
std::string& sharedName,
std::string& sharedSOName,
- std::string& sharedRealName)
+ std::string& sharedRealName,
+ const char* config)
{
// Get the name as if this were a static library.
std::string soName;
std::string realName;
this->GetLibraryNamesInternal(staticName, soName, realName,
- cmTarget::STATIC_LIBRARY);
+ cmTarget::STATIC_LIBRARY, config);
// Get the names as if this were a shared library.
if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -1094,20 +1195,23 @@ void cmTarget::GetLibraryCleanNames(std::string& staticName,
// type will never be MODULE. Either way the only names that
// might have to be cleaned are the shared library names.
this->GetLibraryNamesInternal(sharedName, sharedSOName,
- sharedRealName, cmTarget::SHARED_LIBRARY);
+ sharedRealName, cmTarget::SHARED_LIBRARY,
+ config);
}
else
{
// Use the name of the real type of the library (shared or module).
this->GetLibraryNamesInternal(sharedName, sharedSOName,
- sharedRealName, this->GetType());
+ sharedRealName, this->GetType(),
+ config);
}
}
void cmTarget::GetLibraryNamesInternal(std::string& name,
std::string& soName,
std::string& realName,
- TargetType type)
+ TargetType type,
+ const char* config)
{
// Construct the name of the soname flag variable for this language.
const char* ll =
@@ -1140,7 +1244,7 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
}
// The library name.
- name = this->GetFullNameInternal(type);
+ name = this->GetFullNameInternal(type, config);
// The library's soname.
soName = name;
@@ -1165,22 +1269,26 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
}
void cmTarget::GetExecutableNames(std::string& name,
- std::string& realName)
+ std::string& realName,
+ const char* config)
{
// Get the names based on the real type of the executable.
- this->GetExecutableNamesInternal(name, realName, this->GetType());
+ this->GetExecutableNamesInternal(name, realName, this->GetType(), config);
}
void cmTarget::GetExecutableCleanNames(std::string& name,
- std::string& realName)
+ std::string& realName,
+ const char* config)
{
// Get the name and versioned name of this executable.
- this->GetExecutableNamesInternal(name, realName, cmTarget::EXECUTABLE);
+ this->GetExecutableNamesInternal(name, realName, cmTarget::EXECUTABLE,
+ config);
}
void cmTarget::GetExecutableNamesInternal(std::string& name,
std::string& realName,
- TargetType type)
+ TargetType type,
+ const char* config)
{
// This versioning is supported only for executables and then only
// when the platform supports symbolic links.
@@ -1196,7 +1304,7 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
#endif
// The executable name.
- name = this->GetFullNameInternal(type);
+ name = this->GetFullNameInternal(type, config);
// The executable's real name on disk.
realName = name;