summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-08-11 20:23:02 (GMT)
committerBrad King <brad.king@kitware.com>2008-08-11 20:23:02 (GMT)
commite322d288af7a2e9f413a703e07399976377c7dd0 (patch)
treee6b7c9d816deaacc25a7df4ac90d8ba337da0581 /Source
parent881a0345d0504ebc2301ba9e234bc4dbbdbaf342 (diff)
downloadCMake-e322d288af7a2e9f413a703e07399976377c7dd0.zip
CMake-e322d288af7a2e9f413a703e07399976377c7dd0.tar.gz
CMake-e322d288af7a2e9f413a703e07399976377c7dd0.tar.bz2
ENH: Simple specification of link interfaces
Create an INTERFACE option to the target_link_libraries command to help set the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG properties. This will help users specify link interfaces using variables from Find*.cmake modules that include the 'debug' and 'optimized' keywords.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx77
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h46
2 files changed, 111 insertions, 12 deletions
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 73bb5a5..21acf80 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -40,17 +40,39 @@ bool cmTargetLinkLibrariesCommand
return true;
}
+ // Lookup the target for which libraries are specified.
+ this->Target =
+ this->Makefile->GetCMakeInstance()
+ ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+ if(!this->Target)
+ {
+ cmOStringStream e;
+ e << "Cannot specify link libraries for target \"" << args[0] << "\" "
+ << "which is not built by this project.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
// Keep track of link configuration specifiers.
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
bool haveLLT = false;
+ // Start with primary linking and switch to link interface
+ // specification when the keyword is encountered.
+ this->DoingInterface = false;
+
// add libraries, nothe that there is an optional prefix
// of debug and optimized than can be used
std::vector<std::string>::const_iterator i = args.begin();
for(++i; i != args.end(); ++i)
{
- if(*i == "debug")
+ if(*i == "INTERFACE")
+ {
+ this->DoingInterface = true;
+ }
+ else if(*i == "debug")
{
if(haveLLT)
{
@@ -81,8 +103,7 @@ bool cmTargetLinkLibrariesCommand
{
// The link type was specified by the previous argument.
haveLLT = false;
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),
- i->c_str(), llt);
+ this->HandleLibrary(i->c_str(), llt);
}
else
{
@@ -108,7 +129,7 @@ bool cmTargetLinkLibrariesCommand
llt = cmTarget::OPTIMIZED;
}
}
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),llt);
+ this->HandleLibrary(i->c_str(), llt);
}
}
@@ -122,6 +143,15 @@ bool cmTargetLinkLibrariesCommand
cmSystemTools::SetFatalErrorOccured();
}
+ // If the INTERFACE option was given, make sure the
+ // LINK_INTERFACE_LIBRARIES property exists. This allows the
+ // command to be used to specify an empty link interface.
+ if(this->DoingInterface &&
+ !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES"))
+ {
+ this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
+ }
+
return true;
}
@@ -137,3 +167,42 @@ cmTargetLinkLibrariesCommand
<< "The first specifier will be ignored.";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
+
+//----------------------------------------------------------------------------
+void
+cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
+ cmTarget::LinkLibraryType llt)
+{
+ // Handle normal case first.
+ if(!this->DoingInterface)
+ {
+ this->Makefile
+ ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
+ return;
+ }
+
+ // Include this library in the link interface for the target.
+ if(llt == cmTarget::DEBUG)
+ {
+ // Put in only the DEBUG configuration interface.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib);
+ }
+ else if(llt == cmTarget::OPTIMIZED)
+ {
+ // Put in only the non-DEBUG configuration interface.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+
+ // Make sure the DEBUG configuration interface exists so that this
+ // one will not be used as a fall-back.
+ if(!this->Target->GetProperty("LINK_INTERFACE_LIBRARIES_DEBUG"))
+ {
+ this->Target->SetProperty("LINK_INTERFACE_LIBRARIES_DEBUG", "");
+ }
+ }
+ else
+ {
+ // Put in both the DEBUG and non-DEBUG configuration interfaces.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib);
+ }
+}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index ccf86ad..6a9c0f4 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -64,23 +64,53 @@ public:
virtual const char* GetFullDocumentation()
{
return
- " target_link_libraries(target library1\n"
- " <debug | optimized | general> library2\n"
- " ...)\n"
+ " target_link_libraries(<target> [INTERFACE]\n"
+ " [[debug|optimized|general] <lib>] ...)\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. general indicates it is used for all build types "
- "and is assumed if not specified.\n"
"If any library name matches that of a target in the current project "
"a dependency will automatically be added in the build system to make "
- "sure the library being linked is up-to-date before the target links.";
+ "sure the library being linked is up-to-date before the target links."
+ "\n"
+ "A \"debug\", \"optimized\", or \"general\" keyword indicates that "
+ "the library immediately following it is to be used only for the "
+ "corresponding build configuration. "
+ "The \"debug\" keyword corresponds to the Debug configuration. "
+ "The \"optimized\" keyword corresponds to all other configurations. "
+ "The \"general\" keyword corresponds to all configurations, and is "
+ "purely optional (assumed if omitted). "
+ "Higher granularity may be achieved for per-configuration rules "
+ "by creating and linking to IMPORTED library targets. "
+ "See the IMPORTED mode of the add_library command for more "
+ "information. "
+ "\n"
+ "Library dependencies are transitive by default. "
+ "When this target is linked into another target then the libraries "
+ "linked to this target will appear on the link line for the other "
+ "target too. "
+ "See the LINK_INTERFACE_LIBRARIES target property to override the "
+ "set of transitive link dependencies for a target."
+ "\n"
+ "The INTERFACE option tells the command to append the libraries "
+ "to the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+ "target properties instead of using them for linking. "
+ "Libraries specified as \"debug\" are appended to the "
+ "the LINK_INTERFACE_LIBRARIES_DEBUG property. "
+ "Libraries specified as \"optimized\" are appended to the "
+ "the LINK_INTERFACE_LIBRARIES property. "
+ "Libraries specified as \"general\" (or without any keyword) are "
+ "appended to both properties."
+ ;
}
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
private:
void LinkLibraryTypeSpecifierWarning(int left, int right);
static const char* LinkLibraryTypeNames[3];
+
+ cmTarget* Target;
+ bool DoingInterface;
+
+ void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
};