summaryrefslogtreecommitdiffstats
path: root/Source/cmTargetLinkLibrariesCommand.cxx
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-06-04 14:21:33 (GMT)
committerBrad King <brad.king@kitware.com>2013-07-24 15:52:44 (GMT)
commitb655865bbf85e0bb9587dea099c5996836f48cb8 (patch)
treef8f7e299fc5eced4a6f100e1067622bb8f52d767 /Source/cmTargetLinkLibrariesCommand.cxx
parent828ddb68139a080594c2e6a96d57cb9e93d2ccb3 (diff)
downloadCMake-b655865bbf85e0bb9587dea099c5996836f48cb8.zip
CMake-b655865bbf85e0bb9587dea099c5996836f48cb8.tar.gz
CMake-b655865bbf85e0bb9587dea099c5996836f48cb8.tar.bz2
target_link_libraries: Add PUBLIC/PRIVATE/INTERFACE keyword signature
Add a new signature to help populate INTERFACE_LINK_LIBRARIES and LINK_LIBRARIES cleanly in a single call. Add policy CMP0023 to control whether the keyword signatures can be mixed with uses of the plain signatures on the same target.
Diffstat (limited to 'Source/cmTargetLinkLibrariesCommand.cxx')
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx137
1 files changed, 124 insertions, 13 deletions
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index c5f490e..0ee9420 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -116,7 +116,7 @@ bool cmTargetLinkLibrariesCommand
{
if(args[i] == "LINK_INTERFACE_LIBRARIES")
{
- this->CurrentProcessingState = ProcessingLinkInterface;
+ this->CurrentProcessingState = ProcessingPlainLinkInterface;
if(i != 1)
{
this->Makefile->IssueMessage(
@@ -127,9 +127,26 @@ bool cmTargetLinkLibrariesCommand
return true;
}
}
+ else if(args[i] == "INTERFACE")
+ {
+ if(i != 1
+ && this->CurrentProcessingState != ProcessingKeywordPrivateInterface
+ && this->CurrentProcessingState != ProcessingKeywordPublicInterface
+ && this->CurrentProcessingState != ProcessingKeywordLinkInterface)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The INTERFACE option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ this->CurrentProcessingState = ProcessingKeywordLinkInterface;
+ }
else if(args[i] == "LINK_PUBLIC")
{
- if(i != 1 && this->CurrentProcessingState != ProcessingPrivateInterface)
+ if(i != 1
+ && this->CurrentProcessingState != ProcessingPlainPrivateInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -138,11 +155,28 @@ bool cmTargetLinkLibrariesCommand
);
return true;
}
- this->CurrentProcessingState = ProcessingPublicInterface;
+ this->CurrentProcessingState = ProcessingPlainPublicInterface;
+ }
+ else if(args[i] == "PUBLIC")
+ {
+ if(i != 1
+ && this->CurrentProcessingState != ProcessingKeywordPrivateInterface
+ && this->CurrentProcessingState != ProcessingKeywordPublicInterface
+ && this->CurrentProcessingState != ProcessingKeywordLinkInterface)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The PUBLIC or PRIVATE option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ this->CurrentProcessingState = ProcessingKeywordPublicInterface;
}
else if(args[i] == "LINK_PRIVATE")
{
- if(i != 1 && this->CurrentProcessingState != ProcessingPublicInterface)
+ if(i != 1
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -151,7 +185,23 @@ bool cmTargetLinkLibrariesCommand
);
return true;
}
- this->CurrentProcessingState = ProcessingPrivateInterface;
+ this->CurrentProcessingState = ProcessingPlainPrivateInterface;
+ }
+ else if(args[i] == "PRIVATE")
+ {
+ if(i != 1
+ && this->CurrentProcessingState != ProcessingKeywordPrivateInterface
+ && this->CurrentProcessingState != ProcessingKeywordPublicInterface
+ && this->CurrentProcessingState != ProcessingKeywordLinkInterface)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The PUBLIC or PRIVATE option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ this->CurrentProcessingState = ProcessingKeywordPrivateInterface;
}
else if(args[i] == "debug")
{
@@ -184,7 +234,10 @@ bool cmTargetLinkLibrariesCommand
{
// The link type was specified by the previous argument.
haveLLT = false;
- this->HandleLibrary(args[i].c_str(), llt);
+ if (!this->HandleLibrary(args[i].c_str(), llt))
+ {
+ return false;
+ }
}
else
{
@@ -210,7 +263,10 @@ bool cmTargetLinkLibrariesCommand
llt = cmTarget::OPTIMIZED;
}
}
- this->HandleLibrary(args[i].c_str(), llt);
+ if (!this->HandleLibrary(args[i].c_str(), llt))
+ {
+ return false;
+ }
}
}
@@ -257,16 +313,69 @@ cmTargetLinkLibrariesCommand
}
//----------------------------------------------------------------------------
-void
+bool
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
{
+ cmTarget::TLLSignature sig =
+ (this->CurrentProcessingState == ProcessingPlainPrivateInterface
+ || this->CurrentProcessingState == ProcessingPlainPublicInterface
+ || this->CurrentProcessingState == ProcessingKeywordPrivateInterface
+ || this->CurrentProcessingState == ProcessingKeywordPublicInterface
+ || this->CurrentProcessingState == ProcessingKeywordLinkInterface)
+ ? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature;
+ if (!this->Target->PushTLLCommandTrace(sig))
+ {
+ const char *modal = 0;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0023))
+ {
+ case cmPolicies::WARN:
+ modal = "should";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ modal = "must";
+ messageType = cmake::FATAL_ERROR;
+ }
+
+ if(modal)
+ {
+ cmOStringStream e;
+ // If the sig is a keyword form and there is a conflict, the existing
+ // form must be the plain form.
+ const char *existingSig
+ = (sig == cmTarget::KeywordTLLSignature ? "plain"
+ : "keyword");
+ e << this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0023) << "\n"
+ "The " << existingSig << " signature for target_link_libraries "
+ "has already been used with the target \""
+ << this->Target->GetName() << "\". All uses of "
+ "target_link_libraries with a target " << modal << " be either "
+ "all-keyword or all-plain.\n";
+ this->Target->GetTllSignatureTraces(e,
+ sig == cmTarget::KeywordTLLSignature
+ ? cmTarget::PlainTLLSignature
+ : cmTarget::KeywordTLLSignature);
+ this->Makefile->IssueMessage(messageType, e.str().c_str());
+ if(messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
// Handle normal case first.
- if(this->CurrentProcessingState != ProcessingLinkInterface)
+ if(this->CurrentProcessingState != ProcessingKeywordLinkInterface
+ && this->CurrentProcessingState != ProcessingPlainLinkInterface)
{
this->Makefile
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
- if (this->CurrentProcessingState != ProcessingPublicInterface)
+ if (this->CurrentProcessingState != ProcessingKeywordPublicInterface
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
{
@@ -275,8 +384,9 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
this->Target->GetDebugGeneratorExpressions(lib, llt) +
">").c_str());
}
- // Not LINK_INTERFACE_LIBRARIES or LINK_PUBLIC, do not add to interface.
- return;
+ // Not a 'public' or 'interface' library. Do not add to interface
+ // property.
+ return true;
}
}
@@ -289,7 +399,7 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
if (policy22Status != cmPolicies::OLD
&& policy22Status != cmPolicies::WARN)
{
- return;
+ return true;
}
// Get the list of configurations considered to be DEBUG.
@@ -327,4 +437,5 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
}
}
}
+ return true;
}