ENH: Tolerate repeated link library types
The "debug", "optimized", and "general" link library type specifier arguments to the target_link_library commands are sometimes repeated in user code due to variable expansion and other complications. Instead of silently accepting the duplicates and trying to link to a bogus library like "optimized.lib", warn and ignore the earlier specifiers.
This commit is contained in:
parent
2bbb1713de
commit
40fc9174e2
@ -16,6 +16,13 @@
|
|||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
#include "cmTargetLinkLibrariesCommand.h"
|
#include "cmTargetLinkLibrariesCommand.h"
|
||||||
|
|
||||||
|
const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
|
||||||
|
{
|
||||||
|
"general",
|
||||||
|
"debug",
|
||||||
|
"optimized"
|
||||||
|
};
|
||||||
|
|
||||||
// cmTargetLinkLibrariesCommand
|
// cmTargetLinkLibrariesCommand
|
||||||
bool cmTargetLinkLibrariesCommand
|
bool cmTargetLinkLibrariesCommand
|
||||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||||
@ -32,57 +39,60 @@ bool cmTargetLinkLibrariesCommand
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep track of link configuration specifiers.
|
||||||
|
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
|
||||||
|
bool haveLLT = 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 == "debug")
|
||||||
{
|
{
|
||||||
++i;
|
if(haveLLT)
|
||||||
if(i == args.end())
|
|
||||||
{
|
{
|
||||||
this->SetError
|
this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::DEBUG);
|
||||||
("The \"debug\" argument must be followed by a library");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
|
llt = cmTarget::DEBUG;
|
||||||
cmTarget::DEBUG);
|
haveLLT = true;
|
||||||
}
|
}
|
||||||
else if (*i == "optimized")
|
else if(*i == "optimized")
|
||||||
{
|
{
|
||||||
++i;
|
if(haveLLT)
|
||||||
if(i == args.end())
|
|
||||||
{
|
{
|
||||||
this->SetError(
|
this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::OPTIMIZED);
|
||||||
"The \"optimized\" argument must be followed by a library");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
|
llt = cmTarget::OPTIMIZED;
|
||||||
cmTarget::OPTIMIZED);
|
haveLLT = true;
|
||||||
}
|
}
|
||||||
else if (*i == "general")
|
else if(*i == "general")
|
||||||
{
|
{
|
||||||
++i;
|
if(haveLLT)
|
||||||
if(i == args.end())
|
|
||||||
{
|
{
|
||||||
this->SetError(
|
this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::GENERAL);
|
||||||
"The \"general\" argument must be followed by a library");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
|
llt = cmTarget::GENERAL;
|
||||||
cmTarget::GENERAL);
|
haveLLT = true;
|
||||||
|
}
|
||||||
|
else if(haveLLT)
|
||||||
|
{
|
||||||
|
// The link type was specified by the previous argument.
|
||||||
|
haveLLT = false;
|
||||||
|
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),
|
||||||
|
i->c_str(), llt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// make sure the type is correct if it is currently general. So if you
|
// Lookup old-style cache entry if type is unspecified. So if you
|
||||||
// do a target_link_libraries(foo optimized bar) it will stay optimized
|
// 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
|
// 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
|
// specifed that a library is both debug and optimized. (this check is
|
||||||
// only there for backwards compatibility when mixing projects built
|
// only there for backwards compatibility when mixing projects built
|
||||||
// with old versions of CMake and new)
|
// with old versions of CMake and new)
|
||||||
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
|
llt = cmTarget::GENERAL;
|
||||||
std::string linkType = args[0];
|
std::string linkType = args[0];
|
||||||
linkType += "_LINK_TYPE";
|
linkType += "_LINK_TYPE";
|
||||||
const char* linkTypeString =
|
const char* linkTypeString =
|
||||||
@ -101,5 +111,29 @@ bool cmTargetLinkLibrariesCommand
|
|||||||
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),llt);
|
this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),llt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the last argument was not a library type specifier.
|
||||||
|
if(haveLLT)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "The \"" << this->LinkLibraryTypeNames[llt]
|
||||||
|
<< "\" argument must be followed by a library.";
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmTargetLinkLibrariesCommand
|
||||||
|
::LinkLibraryTypeSpecifierWarning(int left, int right)
|
||||||
|
{
|
||||||
|
cmOStringStream w;
|
||||||
|
w << "Link library type specifier \""
|
||||||
|
<< this->LinkLibraryTypeNames[left] << "\" is followed by specifier \""
|
||||||
|
<< this->LinkLibraryTypeNames[right] << "\" instead of a library name. "
|
||||||
|
<< "The first specifier will be ignored.";
|
||||||
|
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||||
|
}
|
||||||
|
@ -79,6 +79,8 @@ public:
|
|||||||
|
|
||||||
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
|
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
|
||||||
private:
|
private:
|
||||||
|
void LinkLibraryTypeSpecifierWarning(int left, int right);
|
||||||
|
static const char* LinkLibraryTypeNames[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user