summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKen Martin <ken.martin@kitware.com>2006-11-29 16:00:17 (GMT)
committerKen Martin <ken.martin@kitware.com>2006-11-29 16:00:17 (GMT)
commitdaa6d2bc04ff8631559ffcb5141f197cac33e755 (patch)
tree34559ea255e91d274cfa9d38ed7be7f01a906546 /Source
parente9a80cd8a90c3309d32df58b27dcc6e061f5928f (diff)
downloadCMake-daa6d2bc04ff8631559ffcb5141f197cac33e755.zip
CMake-daa6d2bc04ff8631559ffcb5141f197cac33e755.tar.gz
CMake-daa6d2bc04ff8631559ffcb5141f197cac33e755.tar.bz2
ENH: updated handling of debug and optimized target link libraries
Diffstat (limited to 'Source')
-rw-r--r--Source/cmMakefile.cxx20
-rw-r--r--Source/cmTarget.cxx150
-rw-r--r--Source/cmTarget.h37
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx37
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h5
5 files changed, 113 insertions, 136 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 488c41c..3bb4c6c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -959,26 +959,6 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
}
}
}
- // make sure the type is correct if it is currently
- // general. So if you do a
- // target_link_libraries(foo optimized bar) it will stay
- // optimized and not use the lookup. As there maybe the
- // case where someone has specifed that a library is both
- // debug and optimized.
- std::string linkType = lib;
- linkType += "_LINK_TYPE";
- const char* linkTypeString = this->GetDefinition( linkType.c_str() );
- if(llt == cmTarget::GENERAL && linkTypeString)
- {
- if(strcmp(linkTypeString, "debug") == 0)
- {
- llt = cmTarget::DEBUG;
- }
- if(strcmp(linkTypeString, "optimized") == 0)
- {
- llt = cmTarget::OPTIMIZED;
- }
- }
i->second.AddLinkLibrary( *this, target, lib, llt );
}
else
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bfbfdeb..04712c0 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -500,58 +500,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
this->LinkLibraries.push_back( std::pair<std::string,
cmTarget::LinkLibraryType>(lib,llt) );
- if(llt != cmTarget::GENERAL)
- {
- // Store the library's link type in the cache. If it is a
- // conflicting type then assume it is always used. This is the
- // case when the user sets the cache entries for debug and
- // optimized versions of the library to the same value.
- std::string linkTypeName = lib;
- linkTypeName += "_LINK_TYPE";
- switch(llt)
- {
- case cmTarget::DEBUG:
- {
- const char* def = mf.GetDefinition(linkTypeName.c_str());
- if(!def || strcmp(def, "debug") == 0)
- {
- mf.AddCacheDefinition(linkTypeName.c_str(),
- "debug",
- "Library is used for debug links only",
- cmCacheManager::STATIC);
- }
- else
- {
- mf.AddCacheDefinition
- (linkTypeName.c_str(), "general",
- "Library is used for both debug and optimized links",
- cmCacheManager::STATIC);
- }
- }
- break;
- case cmTarget::OPTIMIZED:
- {
- const char* def = mf.GetDefinition(linkTypeName.c_str());
- if(!def || strcmp(def, "optimized") == 0)
- {
- mf.AddCacheDefinition
- (linkTypeName.c_str(), "optimized",
- "Library is used for debug links only",
- cmCacheManager::STATIC);
- }
- else
- {
- mf.AddCacheDefinition
- (linkTypeName.c_str(), "general",
- "Library is used for both debug and optimized links",
- cmCacheManager::STATIC);
- }
- }
- break;
- case cmTarget::GENERAL:
- break;
- }
- }
// Add the explicit dependency information for this target. This is
// simply a set of libraries separated by ";". There should always
// be a trailing ";". These library names are not canonical, in that
@@ -570,6 +518,19 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
{
dependencies += old_val;
}
+ switch (llt)
+ {
+ case cmTarget::GENERAL:
+ dependencies += "general";
+ break;
+ case cmTarget::DEBUG:
+ dependencies += "debug";
+ break;
+ case cmTarget::OPTIMIZED:
+ dependencies += "optimized";
+ break;
+ }
+ dependencies += ";";
dependencies += lib;
dependencies += ";";
mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
@@ -667,7 +628,7 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
= this->LinkLibraries.rbegin();
lib != this->LinkLibraries.rend(); ++lib)
{
- this->GatherDependencies( mf, lib->first, dep_map );
+ this->GatherDependencies( mf, *lib, dep_map);
}
// 2. Remove any dependencies that are already satisfied in the original
@@ -679,7 +640,7 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
for( LinkLibraryVectorType::iterator lib2 = lib;
lib2 != this->LinkLibraries.end(); ++lib2)
{
- DeleteDependency( dep_map, lib->first, lib2->first );
+ this->DeleteDependency( dep_map, *lib, *lib2);
}
}
@@ -687,8 +648,8 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// 3. Create the new link line by simply emitting any dependencies that are
// missing. Start from the back and keep adding.
//
- std::set<cmStdString> done, visited;
- std::vector<std::string> newLinkLibraries;
+ std::set<DependencyMap::key_type> done, visited;
+ std::vector<DependencyMap::key_type> newLinkLibraries;
for(LinkLibraryVectorType::reverse_iterator lib =
this->LinkLibraries.rbegin();
lib != this->LinkLibraries.rend(); ++lib)
@@ -697,47 +658,33 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// if a variable expands to nothing.
if (lib->first.size() != 0)
{
- Emit( lib->first, dep_map, done, visited, newLinkLibraries );
+ this->Emit( *lib, dep_map, done, visited, newLinkLibraries );
}
}
// 4. Add the new libraries to the link line.
//
- for( std::vector<std::string>::reverse_iterator k =
+ for( std::vector<DependencyMap::key_type>::reverse_iterator k =
newLinkLibraries.rbegin();
k != newLinkLibraries.rend(); ++k )
{
- std::string linkType = *k;
- linkType += "_LINK_TYPE";
- cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
- const char* linkTypeString = mf.GetDefinition( linkType.c_str() );
- if(linkTypeString)
- {
- if(strcmp(linkTypeString, "debug") == 0)
- {
- llt = cmTarget::DEBUG;
- }
- if(strcmp(linkTypeString, "optimized") == 0)
- {
- llt = cmTarget::OPTIMIZED;
- }
- }
- this->LinkLibraries.push_back( std::make_pair(*k,llt) );
+ // get the llt from the dep_map
+ this->LinkLibraries.push_back( std::make_pair(k->first,k->second) );
}
this->LinkLibrariesAnalyzed = true;
}
void cmTarget::InsertDependency( DependencyMap& depMap,
- const cmStdString& lib,
- const cmStdString& dep )
+ const LibraryID& lib,
+ const LibraryID& dep)
{
depMap[lib].push_back(dep);
}
void cmTarget::DeleteDependency( DependencyMap& depMap,
- const cmStdString& lib,
- const cmStdString& dep )
+ const LibraryID& lib,
+ const LibraryID& dep)
{
// Make sure there is an entry in the map for lib. If so, delete all
// dependencies to dep. There may be repeated entries because of
@@ -755,11 +702,11 @@ void cmTarget::DeleteDependency( DependencyMap& depMap,
}
}
-void cmTarget::Emit( const std::string& lib,
- const DependencyMap& dep_map,
- std::set<cmStdString>& emitted,
- std::set<cmStdString>& visited,
- std::vector<std::string>& link_line )
+void cmTarget::Emit(const LibraryID lib,
+ const DependencyMap& dep_map,
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line )
{
// It's already been emitted
if( emitted.find(lib) != emitted.end() )
@@ -790,7 +737,7 @@ void cmTarget::Emit( const std::string& lib,
// recursive call. This way, if we come across a library that
// has already been emitted, we repeat it iff it has been
// emitted here.
- std::set<cmStdString> emitted_here;
+ std::set<DependencyMap::key_type> emitted_here;
for( i = dep_on.rbegin(); i != dep_on.rend(); ++i )
{
if( emitted_here.find(*i) != emitted_here.end() )
@@ -819,8 +766,8 @@ void cmTarget::Emit( const std::string& lib,
void cmTarget::GatherDependencies( const cmMakefile& mf,
- const std::string& lib,
- DependencyMap& dep_map )
+ const LibraryID& lib,
+ DependencyMap& dep_map)
{
// If the library is already in the dependency map, then it has
// already been fully processed.
@@ -829,7 +776,7 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
return;
}
- const char* deps = mf.GetDefinition( (lib+"_LIB_DEPENDS").c_str() );
+ const char* deps = mf.GetDefinition( (lib.first+"_LIB_DEPENDS").c_str() );
if( deps && strcmp(deps,"") != 0 )
{
// Make sure this library is in the map, even if it has an empty
@@ -837,8 +784,9 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
// no dependencies with that of unspecified dependencies.
dep_map[lib];
- // Parse the dependency information, which is simply a set of
- // libraries separated by ";". There is always a trailing ";".
+ // Parse the dependency information, which is a set of
+ // type, library pairs separated by ";". There is always a trailing ";".
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
std::string depline = deps;
std::string::size_type start = 0;
std::string::size_type end;
@@ -848,13 +796,31 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
std::string l = depline.substr( start, end-start );
if( l.size() != 0 )
{
- InsertDependency( dep_map, lib, l );
- GatherDependencies( mf, l, dep_map );
+ if (l == "debug")
+ {
+ llt = cmTarget::DEBUG;
+ }
+ else if (l == "optimized")
+ {
+ llt = cmTarget::OPTIMIZED;
+ }
+ else if (l == "general")
+ {
+ llt = cmTarget::GENERAL;
+ }
+ else
+ {
+ LibraryID lib2(l,llt);
+ this->InsertDependency( dep_map, lib, lib2);
+ this->GatherDependencies( mf, lib2, dep_map);
+ llt = cmTarget::GENERAL;
+ }
}
start = end+1; // skip the ;
end = depline.find( ";", start );
}
- DeleteDependency( dep_map, lib, lib); // cannot depend on itself
+ // cannot depend on itself
+ this->DeleteDependency( dep_map, lib, lib);
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index dc39f80..d6e3f8d 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -95,8 +95,10 @@ public:
*/
enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};
- typedef std::vector<std::pair<std::string,LinkLibraryType> >
- LinkLibraryVectorType;
+ //* how we identify a library, by name and type
+ typedef std::pair<cmStdString, LinkLibraryType> LibraryID;
+
+ typedef std::vector<LibraryID > LinkLibraryVectorType;
const LinkLibraryVectorType &GetLinkLibraries() {
return this->LinkLibraries;}
const LinkLibraryVectorType &GetOriginalLinkLibraries()
@@ -251,7 +253,7 @@ private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
*/
- typedef std::vector<cmStdString> DependencyList;
+ typedef std::vector< LibraryID > DependencyList;
/**
* This map holds the dependency graph. map[x] returns a set of
@@ -259,27 +261,21 @@ private:
* ordered. This is necessary to handle direct dependencies that
* themselves have no dependency information.
*/
- typedef std::map< cmStdString, std::vector< cmStdString > > DependencyMap;
-
- /**
- * Maps a library name to its internal structure
- */
- typedef std::map< cmStdString, std::pair<cmStdString,LinkLibraryType> >
- LibTypeMap;
+ typedef std::map< LibraryID, DependencyList > DependencyMap;
/**
* Inserts \a dep at the end of the dependency list of \a lib.
*/
void InsertDependency( DependencyMap& depMap,
- const cmStdString& lib,
- const cmStdString& dep );
+ const LibraryID& lib,
+ const LibraryID& dep);
/*
* Deletes \a dep from the dependency list of \a lib.
*/
void DeleteDependency( DependencyMap& depMap,
- const cmStdString& lib,
- const cmStdString& dep );
+ const LibraryID& lib,
+ const LibraryID& dep);
/**
* Emits the library \a lib and all its dependencies into link_line.
@@ -289,18 +285,19 @@ private:
* link_line is in reverse order, in that the dependencies of a
* library are listed before the library itself.
*/
- void Emit( const std::string& lib,
+ void Emit( const LibraryID lib,
const DependencyMap& dep_map,
- std::set<cmStdString>& emitted,
- std::set<cmStdString>& visited,
- std::vector<std::string>& link_line );
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line);
/**
* Finds the dependencies for \a lib and inserts them into \a
* dep_map.
*/
- void GatherDependencies( const cmMakefile& mf, const std::string& lib,
- DependencyMap& dep_map );
+ void GatherDependencies( const cmMakefile& mf,
+ const LibraryID& lib,
+ DependencyMap& dep_map);
const char* GetSuffixVariableInternal(TargetType type, bool implib);
const char* GetPrefixVariableInternal(TargetType type, bool implib);
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index af5ecb1..2b649b1 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -62,10 +62,43 @@ bool cmTargetLinkLibrariesCommand::InitialPass(std::vector<std::string>
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
cmTarget::OPTIMIZED);
}
- else
+ else if (*i == "general")
{
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError(
+ "The \"general\" argument must be followed by a library");
+ return false;
+ }
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
- cmTarget::GENERAL);
+ cmTarget::GENERAL);
+ }
+ else
+ {
+ // make sure the type is correct if it is currently general. So if you
+ // do a target_link_libraries(foo optimized bar) it will stay optimized
+ // and not use the lookup. As there maybe the case where someone has
+ // specifed that a library is both debug and optimized. (this check is
+ // only there for backwards compatibility when mixing projects built
+ // with old versions of CMake and new)
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ std::string linkType = args[0];
+ linkType += "_LINK_TYPE";
+ const char* linkTypeString =
+ this->Makefile->GetDefinition( linkType.c_str() );
+ if(linkTypeString)
+ {
+ if(strcmp(linkTypeString, "debug") == 0)
+ {
+ llt = cmTarget::DEBUG;
+ }
+ if(strcmp(linkTypeString, "optimized") == 0)
+ {
+ llt = cmTarget::OPTIMIZED;
+ }
+ }
+ this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),llt);
}
}
return true;
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 8191ec8..4d08c33 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -64,12 +64,13 @@ public:
{
return
" TARGET_LINK_LIBRARIES(target library1\n"
- " <debug | optimized> library2\n"
+ " <debug | optimized | general> library2\n"
" ...)\n"
"Specify a list of libraries to be linked into the specified target. "
"The debug and optimized strings may be used to indicate that "
"the next library listed is to be used only for that specific "
- "type of build";
+ "type of build. general indicates it is used for all build types "
+ "and is assumed if not specified.";
}
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);