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.
This commit is contained in:
parent
881a0345d0
commit
e322d288af
|
@ -40,17 +40,39 @@ bool cmTargetLinkLibrariesCommand
|
||||||
return true;
|
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.
|
// Keep track of link configuration specifiers.
|
||||||
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
|
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
|
||||||
bool haveLLT = false;
|
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
|
// add libraries, nothe that there is an optional prefix
|
||||||
// of debug and optimized than can be used
|
// of debug and optimized than can be used
|
||||||
std::vector<std::string>::const_iterator i = args.begin();
|
std::vector<std::string>::const_iterator i = args.begin();
|
||||||
|
|
||||||
for(++i; i != args.end(); ++i)
|
for(++i; i != args.end(); ++i)
|
||||||
{
|
{
|
||||||
if(*i == "debug")
|
if(*i == "INTERFACE")
|
||||||
|
{
|
||||||
|
this->DoingInterface = true;
|
||||||
|
}
|
||||||
|
else if(*i == "debug")
|
||||||
{
|
{
|
||||||
if(haveLLT)
|
if(haveLLT)
|
||||||
{
|
{
|
||||||
|
@ -81,8 +103,7 @@ bool cmTargetLinkLibrariesCommand
|
||||||
{
|
{
|
||||||
// The link type was specified by the previous argument.
|
// The link type was specified by the previous argument.
|
||||||
haveLLT = false;
|
haveLLT = false;
|
||||||
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),
|
this->HandleLibrary(i->c_str(), llt);
|
||||||
i->c_str(), llt);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -108,7 +129,7 @@ bool cmTargetLinkLibrariesCommand
|
||||||
llt = cmTarget::OPTIMIZED;
|
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();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,3 +167,42 @@ cmTargetLinkLibrariesCommand
|
||||||
<< "The first specifier will be ignored.";
|
<< "The first specifier will be ignored.";
|
||||||
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -64,23 +64,53 @@ public:
|
||||||
virtual const char* GetFullDocumentation()
|
virtual const char* GetFullDocumentation()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
" target_link_libraries(target library1\n"
|
" target_link_libraries(<target> [INTERFACE]\n"
|
||||||
" <debug | optimized | general> library2\n"
|
" [[debug|optimized|general] <lib>] ...)\n"
|
||||||
" ...)\n"
|
|
||||||
"Specify a list of libraries to be linked into the specified target. "
|
"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 "
|
"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 "
|
"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);
|
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
|
||||||
private:
|
private:
|
||||||
void LinkLibraryTypeSpecifierWarning(int left, int right);
|
void LinkLibraryTypeSpecifierWarning(int left, int right);
|
||||||
static const char* LinkLibraryTypeNames[3];
|
static const char* LinkLibraryTypeNames[3];
|
||||||
|
|
||||||
|
cmTarget* Target;
|
||||||
|
bool DoingInterface;
|
||||||
|
|
||||||
|
void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue