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.
This commit is contained in:
parent
828ddb6813
commit
b655865bbf
|
@ -575,6 +575,32 @@ cmPolicies::cmPolicies()
|
||||||
"property for in-build targets, and ignore the old properties matching "
|
"property for in-build targets, and ignore the old properties matching "
|
||||||
"(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
|
"(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
|
||||||
2,8,11,20130516, cmPolicies::WARN);
|
2,8,11,20130516, cmPolicies::WARN);
|
||||||
|
|
||||||
|
this->DefinePolicy(
|
||||||
|
CMP0023, "CMP0023",
|
||||||
|
"Plain and keyword target_link_libraries signatures cannot be mixed.",
|
||||||
|
"CMake 2.8.12 introduced the target_link_libraries signature using "
|
||||||
|
"the PUBLIC, PRIVATE, and INTERFACE keywords to generalize the "
|
||||||
|
"LINK_PUBLIC and LINK_PRIVATE keywords introduced in CMake 2.8.7. "
|
||||||
|
"Use of signatures with any of these keywords sets the link interface "
|
||||||
|
"of a target explicitly, even if empty. "
|
||||||
|
"This produces confusing behavior when used in combination with the "
|
||||||
|
"historical behavior of the plain target_link_libraries signature. "
|
||||||
|
"For example, consider the code:\n"
|
||||||
|
" target_link_libraries(mylib A)\n"
|
||||||
|
" target_link_libraries(mylib PRIVATE B)\n"
|
||||||
|
"After the first line the link interface has not been set explicitly "
|
||||||
|
"so CMake would use the link implementation, A, as the link interface. "
|
||||||
|
"However, the second line sets the link interface to empty. "
|
||||||
|
"In order to avoid this subtle behavior CMake now prefers to disallow "
|
||||||
|
"mixing the plain and keyword signatures of target_link_libraries for "
|
||||||
|
"a single target."
|
||||||
|
"\n"
|
||||||
|
"The OLD behavior for this policy is to allow keyword and plain "
|
||||||
|
"target_link_libraries signatures to be mixed. "
|
||||||
|
"The NEW behavior for this policy is to not to allow mixing of the "
|
||||||
|
"keyword and plain signatures.",
|
||||||
|
2,8,11,20130724, cmPolicies::WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmPolicies::~cmPolicies()
|
cmPolicies::~cmPolicies()
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
CMP0021, ///< Fatal error on relative paths in INCLUDE_DIRECTORIES
|
CMP0021, ///< Fatal error on relative paths in INCLUDE_DIRECTORIES
|
||||||
/// target property
|
/// target property
|
||||||
CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface
|
CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface
|
||||||
|
CMP0023, ///< Disallow mixing keyword and plain tll signatures
|
||||||
|
|
||||||
/** \brief Always the last entry.
|
/** \brief Always the last entry.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2493,6 +2493,57 @@ static std::string targetNameGenex(const char *lib)
|
||||||
return std::string("$<TARGET_NAME:") + lib + ">";
|
return std::string("$<TARGET_NAME:") + lib + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::PushTLLCommandTrace(TLLSignature signature)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
if (!this->TLLCommands.empty())
|
||||||
|
{
|
||||||
|
if (this->TLLCommands.back().first != signature)
|
||||||
|
{
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmListFileBacktrace lfbt;
|
||||||
|
this->Makefile->GetBacktrace(lfbt);
|
||||||
|
this->TLLCommands.push_back(std::make_pair(signature, lfbt));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GetTllSignatureTraces(cmOStringStream &s,
|
||||||
|
TLLSignature sig) const
|
||||||
|
{
|
||||||
|
std::vector<cmListFileBacktrace> sigs;
|
||||||
|
typedef std::vector<std::pair<TLLSignature, cmListFileBacktrace> > Container;
|
||||||
|
for(Container::const_iterator it = this->TLLCommands.begin();
|
||||||
|
it != this->TLLCommands.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first == sig)
|
||||||
|
{
|
||||||
|
sigs.push_back(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sigs.empty())
|
||||||
|
{
|
||||||
|
const char *sigString
|
||||||
|
= (sig == cmTarget::KeywordTLLSignature ? "keyword"
|
||||||
|
: "plain");
|
||||||
|
s << "The uses of the " << sigString << " signature are here:\n";
|
||||||
|
for(std::vector<cmListFileBacktrace>::const_iterator it = sigs.begin();
|
||||||
|
it != sigs.end(); ++it)
|
||||||
|
{
|
||||||
|
cmListFileBacktrace::const_iterator i = it->begin();
|
||||||
|
if(i != it->end())
|
||||||
|
{
|
||||||
|
cmListFileContext const& lfc = *i;
|
||||||
|
s << " * " << (lfc.Line? "": " in ") << lfc << std::endl;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
||||||
const char *target, const char* lib,
|
const char *target, const char* lib,
|
||||||
|
|
|
@ -190,6 +190,12 @@ public:
|
||||||
void AddLinkLibrary(cmMakefile& mf,
|
void AddLinkLibrary(cmMakefile& mf,
|
||||||
const char *target, const char* lib,
|
const char *target, const char* lib,
|
||||||
LinkLibraryType llt);
|
LinkLibraryType llt);
|
||||||
|
enum TLLSignature {
|
||||||
|
KeywordTLLSignature,
|
||||||
|
PlainTLLSignature
|
||||||
|
};
|
||||||
|
bool PushTLLCommandTrace(TLLSignature signature);
|
||||||
|
void GetTllSignatureTraces(cmOStringStream &s, TLLSignature sig) const;
|
||||||
|
|
||||||
void MergeLinkLibraries( cmMakefile& mf, const char* selfname,
|
void MergeLinkLibraries( cmMakefile& mf, const char* selfname,
|
||||||
const LinkLibraryVectorType& libs );
|
const LinkLibraryVectorType& libs );
|
||||||
|
@ -548,6 +554,8 @@ private:
|
||||||
// directories.
|
// directories.
|
||||||
std::set<cmStdString> SystemIncludeDirectories;
|
std::set<cmStdString> SystemIncludeDirectories;
|
||||||
|
|
||||||
|
std::vector<std::pair<TLLSignature, cmListFileBacktrace> > TLLCommands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -116,7 +116,7 @@ bool cmTargetLinkLibrariesCommand
|
||||||
{
|
{
|
||||||
if(args[i] == "LINK_INTERFACE_LIBRARIES")
|
if(args[i] == "LINK_INTERFACE_LIBRARIES")
|
||||||
{
|
{
|
||||||
this->CurrentProcessingState = ProcessingLinkInterface;
|
this->CurrentProcessingState = ProcessingPlainLinkInterface;
|
||||||
if(i != 1)
|
if(i != 1)
|
||||||
{
|
{
|
||||||
this->Makefile->IssueMessage(
|
this->Makefile->IssueMessage(
|
||||||
|
@ -127,9 +127,26 @@ bool cmTargetLinkLibrariesCommand
|
||||||
return true;
|
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")
|
else if(args[i] == "LINK_PUBLIC")
|
||||||
{
|
{
|
||||||
if(i != 1 && this->CurrentProcessingState != ProcessingPrivateInterface)
|
if(i != 1
|
||||||
|
&& this->CurrentProcessingState != ProcessingPlainPrivateInterface)
|
||||||
{
|
{
|
||||||
this->Makefile->IssueMessage(
|
this->Makefile->IssueMessage(
|
||||||
cmake::FATAL_ERROR,
|
cmake::FATAL_ERROR,
|
||||||
|
@ -138,11 +155,28 @@ bool cmTargetLinkLibrariesCommand
|
||||||
);
|
);
|
||||||
return true;
|
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")
|
else if(args[i] == "LINK_PRIVATE")
|
||||||
{
|
{
|
||||||
if(i != 1 && this->CurrentProcessingState != ProcessingPublicInterface)
|
if(i != 1
|
||||||
|
&& this->CurrentProcessingState != ProcessingPlainPublicInterface)
|
||||||
{
|
{
|
||||||
this->Makefile->IssueMessage(
|
this->Makefile->IssueMessage(
|
||||||
cmake::FATAL_ERROR,
|
cmake::FATAL_ERROR,
|
||||||
|
@ -151,7 +185,23 @@ bool cmTargetLinkLibrariesCommand
|
||||||
);
|
);
|
||||||
return true;
|
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")
|
else if(args[i] == "debug")
|
||||||
{
|
{
|
||||||
|
@ -184,7 +234,10 @@ 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->HandleLibrary(args[i].c_str(), llt);
|
if (!this->HandleLibrary(args[i].c_str(), llt))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -210,7 +263,10 @@ bool cmTargetLinkLibrariesCommand
|
||||||
llt = cmTarget::OPTIMIZED;
|
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,
|
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||||
cmTarget::LinkLibraryType llt)
|
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.
|
// Handle normal case first.
|
||||||
if(this->CurrentProcessingState != ProcessingLinkInterface)
|
if(this->CurrentProcessingState != ProcessingKeywordLinkInterface
|
||||||
|
&& this->CurrentProcessingState != ProcessingPlainLinkInterface)
|
||||||
{
|
{
|
||||||
this->Makefile
|
this->Makefile
|
||||||
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
|
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
|
||||||
if (this->CurrentProcessingState != ProcessingPublicInterface)
|
if (this->CurrentProcessingState != ProcessingKeywordPublicInterface
|
||||||
|
&& this->CurrentProcessingState != ProcessingPlainPublicInterface)
|
||||||
{
|
{
|
||||||
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
|
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
|
||||||
{
|
{
|
||||||
|
@ -275,8 +384,9 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||||
this->Target->GetDebugGeneratorExpressions(lib, llt) +
|
this->Target->GetDebugGeneratorExpressions(lib, llt) +
|
||||||
">").c_str());
|
">").c_str());
|
||||||
}
|
}
|
||||||
// Not LINK_INTERFACE_LIBRARIES or LINK_PUBLIC, do not add to interface.
|
// Not a 'public' or 'interface' library. Do not add to interface
|
||||||
return;
|
// property.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +399,7 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||||
if (policy22Status != cmPolicies::OLD
|
if (policy22Status != cmPolicies::OLD
|
||||||
&& policy22Status != cmPolicies::WARN)
|
&& policy22Status != cmPolicies::WARN)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list of configurations considered to be DEBUG.
|
// Get the list of configurations considered to be DEBUG.
|
||||||
|
@ -327,4 +437,5 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,16 @@ public:
|
||||||
"directory of the framework will also be processed as a \"usage "
|
"directory of the framework will also be processed as a \"usage "
|
||||||
"requirement\". This has the same effect as passing the framework "
|
"requirement\". This has the same effect as passing the framework "
|
||||||
"directory as an include directory."
|
"directory as an include directory."
|
||||||
|
" target_link_libraries(<target>\n"
|
||||||
|
" <PRIVATE|PUBLIC|INTERFACE> <lib> ...\n"
|
||||||
|
" [<PRIVATE|PUBLIC|INTERFACE> <lib> ... ] ...])\n"
|
||||||
|
"The PUBLIC, PRIVATE and INTERFACE keywords can be used to specify "
|
||||||
|
"both the link dependencies and the link interface in one command. "
|
||||||
|
"Libraries and targets following PUBLIC are linked to, and are "
|
||||||
|
"made part of the link interface. Libraries and targets "
|
||||||
|
"following PRIVATE are linked to, but are not made part of the "
|
||||||
|
"link interface. Libraries following INTERFACE are appended "
|
||||||
|
"to the link interface and are not used for linking <target>."
|
||||||
"\n"
|
"\n"
|
||||||
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
|
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
|
||||||
" [[debug|optimized|general] <lib>] ...)\n"
|
" [[debug|optimized|general] <lib>] ...)\n"
|
||||||
|
@ -120,7 +130,8 @@ public:
|
||||||
"to the INTERFACE_LINK_LIBRARIES target property instead of using them "
|
"to the INTERFACE_LINK_LIBRARIES target property instead of using them "
|
||||||
"for linking. If policy CMP0022 is not NEW, then this mode also "
|
"for linking. If policy CMP0022 is not NEW, then this mode also "
|
||||||
"appends libraries to the LINK_INTERFACE_LIBRARIES and its "
|
"appends libraries to the LINK_INTERFACE_LIBRARIES and its "
|
||||||
"per-configuration equivalent. "
|
"per-configuration equivalent. This signature "
|
||||||
|
"is for compatibility only. Prefer the INTERFACE mode instead. "
|
||||||
"Libraries specified as \"debug\" are wrapped in a generator "
|
"Libraries specified as \"debug\" are wrapped in a generator "
|
||||||
"expression to correspond to debug builds. If policy CMP0022 is not "
|
"expression to correspond to debug builds. If policy CMP0022 is not "
|
||||||
"NEW, the libraries are also appended to the "
|
"NEW, the libraries are also appended to the "
|
||||||
|
@ -139,7 +150,9 @@ public:
|
||||||
" [<LINK_PRIVATE|LINK_PUBLIC>\n"
|
" [<LINK_PRIVATE|LINK_PUBLIC>\n"
|
||||||
" [[debug|optimized|general] <lib>] ...])\n"
|
" [[debug|optimized|general] <lib>] ...])\n"
|
||||||
"The LINK_PUBLIC and LINK_PRIVATE modes can be used to specify both "
|
"The LINK_PUBLIC and LINK_PRIVATE modes can be used to specify both "
|
||||||
"the link dependencies and the link interface in one command. "
|
"the link dependencies and the link interface in one command. This "
|
||||||
|
"signature is for compatibility only. Prefer the PUBLIC or PRIVATE "
|
||||||
|
"keywords instead. "
|
||||||
"Libraries and targets following LINK_PUBLIC are linked to, and are "
|
"Libraries and targets following LINK_PUBLIC are linked to, and are "
|
||||||
"made part of the INTERFACE_LINK_LIBRARIES. If policy CMP0022 is not "
|
"made part of the INTERFACE_LINK_LIBRARIES. If policy CMP0022 is not "
|
||||||
"NEW, they are also made part of the LINK_INTERFACE_LIBRARIES. "
|
"NEW, they are also made part of the LINK_INTERFACE_LIBRARIES. "
|
||||||
|
@ -185,14 +198,17 @@ private:
|
||||||
cmTarget* Target;
|
cmTarget* Target;
|
||||||
enum ProcessingState {
|
enum ProcessingState {
|
||||||
ProcessingLinkLibraries,
|
ProcessingLinkLibraries,
|
||||||
ProcessingLinkInterface,
|
ProcessingPlainLinkInterface,
|
||||||
ProcessingPublicInterface,
|
ProcessingKeywordLinkInterface,
|
||||||
ProcessingPrivateInterface
|
ProcessingPlainPublicInterface,
|
||||||
|
ProcessingKeywordPublicInterface,
|
||||||
|
ProcessingPlainPrivateInterface,
|
||||||
|
ProcessingKeywordPrivateInterface
|
||||||
};
|
};
|
||||||
|
|
||||||
ProcessingState CurrentProcessingState;
|
ProcessingState CurrentProcessingState;
|
||||||
|
|
||||||
void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
|
bool HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -124,3 +124,9 @@ add_library(libConsumer empty.cpp)
|
||||||
target_link_libraries(libConsumer debug depA)
|
target_link_libraries(libConsumer debug depA)
|
||||||
|
|
||||||
add_subdirectory(cmp0022)
|
add_subdirectory(cmp0022)
|
||||||
|
|
||||||
|
add_executable(newsignature1 newsignature1.cpp)
|
||||||
|
target_link_libraries(newsignature1 PRIVATE depC INTERFACE depD PUBLIC depB PRIVATE subdirlib INTERFACE INTERFACE PUBLIC)
|
||||||
|
|
||||||
|
assert_property(newsignature1 INTERFACE_LINK_LIBRARIES "depD;depB")
|
||||||
|
assert_property(newsignature1 LINK_LIBRARIES "depC;depB;subdirlib")
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
#include "depB.h"
|
||||||
|
#include "depC.h"
|
||||||
|
#include "depIfaceOnly.h"
|
||||||
|
|
||||||
|
#include "subdirlib.h"
|
||||||
|
|
||||||
|
int main(int, char **)
|
||||||
|
{
|
||||||
|
DepA a;
|
||||||
|
DepB b;
|
||||||
|
DepC c;
|
||||||
|
|
||||||
|
DepIfaceOnly iface_only;
|
||||||
|
|
||||||
|
SubDirLibObject sd;
|
||||||
|
|
||||||
|
return a.foo() + b.foo() + c.foo() + iface_only.foo() + sd.foo();
|
||||||
|
}
|
|
@ -115,3 +115,4 @@ if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_RunCMake_test(File_Generate)
|
add_RunCMake_test(File_Generate)
|
||||||
|
add_RunCMake_test(target_link_libraries)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,16 @@
|
||||||
|
CMake Error at CMP0023-NEW-2.cmake:11 \(target_link_libraries\):
|
||||||
|
Policy CMP0023 is not set: Plain and keyword target_link_libraries
|
||||||
|
signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
|
||||||
|
details. Use the cmake_policy command to set the policy and suppress this
|
||||||
|
warning.
|
||||||
|
|
||||||
|
The plain signature for target_link_libraries has already been used with
|
||||||
|
the target "foo". All uses of target_link_libraries with a target must be
|
||||||
|
either all-keyword or all-plain.
|
||||||
|
|
||||||
|
The uses of the plain signature are here:
|
||||||
|
|
||||||
|
\* CMP0023-NEW-2.cmake:10 \(target_link_libraries\)
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
project(CMP0022-WARN)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0023 NEW)
|
||||||
|
|
||||||
|
add_library(foo SHARED empty_vs6_1.cpp)
|
||||||
|
add_library(bar SHARED empty_vs6_2.cpp)
|
||||||
|
add_library(bat SHARED empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo bar)
|
||||||
|
target_link_libraries(foo LINK_PRIVATE bat)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,16 @@
|
||||||
|
CMake Error at CMP0023-NEW.cmake:11 \(target_link_libraries\):
|
||||||
|
Policy CMP0023 is not set: Plain and keyword target_link_libraries
|
||||||
|
signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
|
||||||
|
details. Use the cmake_policy command to set the policy and suppress this
|
||||||
|
warning.
|
||||||
|
|
||||||
|
The plain signature for target_link_libraries has already been used with
|
||||||
|
the target "foo". All uses of target_link_libraries with a target must be
|
||||||
|
either all-keyword or all-plain.
|
||||||
|
|
||||||
|
The uses of the plain signature are here:
|
||||||
|
|
||||||
|
\* CMP0023-NEW.cmake:10 \(target_link_libraries\)
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
project(CMP0022-WARN)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0023 NEW)
|
||||||
|
|
||||||
|
add_library(foo SHARED empty_vs6_1.cpp)
|
||||||
|
add_library(bar SHARED empty_vs6_2.cpp)
|
||||||
|
add_library(bat SHARED empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo bar)
|
||||||
|
target_link_libraries(foo PRIVATE bat)
|
|
@ -0,0 +1,16 @@
|
||||||
|
CMake Warning \(dev\) at CMP0023-WARN-2.cmake:9 \(target_link_libraries\):
|
||||||
|
Policy CMP0023 is not set: Plain and keyword target_link_libraries
|
||||||
|
signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
|
||||||
|
details. Use the cmake_policy command to set the policy and suppress this
|
||||||
|
warning.
|
||||||
|
|
||||||
|
The plain signature for target_link_libraries has already been used with
|
||||||
|
the target "foo". All uses of target_link_libraries with a target should
|
||||||
|
be either all-keyword or all-plain.
|
||||||
|
|
||||||
|
The uses of the plain signature are here:
|
||||||
|
|
||||||
|
\* CMP0023-WARN-2.cmake:8 \(target_link_libraries\)
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
project(CMP0022-WARN)
|
||||||
|
|
||||||
|
add_library(foo SHARED empty_vs6_1.cpp)
|
||||||
|
add_library(bar SHARED empty_vs6_2.cpp)
|
||||||
|
add_library(bat SHARED empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo bar)
|
||||||
|
target_link_libraries(foo LINK_PRIVATE bat)
|
|
@ -0,0 +1,16 @@
|
||||||
|
CMake Warning \(dev\) at CMP0023-WARN.cmake:9 \(target_link_libraries\):
|
||||||
|
Policy CMP0023 is not set: Plain and keyword target_link_libraries
|
||||||
|
signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
|
||||||
|
details. Use the cmake_policy command to set the policy and suppress this
|
||||||
|
warning.
|
||||||
|
|
||||||
|
The plain signature for target_link_libraries has already been used with
|
||||||
|
the target "foo". All uses of target_link_libraries with a target should
|
||||||
|
be either all-keyword or all-plain.
|
||||||
|
|
||||||
|
The uses of the plain signature are here:
|
||||||
|
|
||||||
|
\* CMP0023-WARN.cmake:8 \(target_link_libraries\)
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
project(CMP0022-WARN)
|
||||||
|
|
||||||
|
add_library(foo SHARED empty_vs6_1.cpp)
|
||||||
|
add_library(bar SHARED empty_vs6_2.cpp)
|
||||||
|
add_library(bat SHARED empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo bar)
|
||||||
|
target_link_libraries(foo PRIVATE bat)
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at MixedSignature.cmake:6 \(target_link_libraries\):
|
||||||
|
The PUBLIC or PRIVATE option must appear as the second argument, just after
|
||||||
|
the target name.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
add_library(foo empty_vs6_1.cpp)
|
||||||
|
add_library(bar empty_vs6_2.cpp)
|
||||||
|
add_library(bat empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo LINK_PUBLIC bar PRIVATE bat)
|
|
@ -0,0 +1,8 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CMP0023-WARN)
|
||||||
|
run_cmake(CMP0023-NEW)
|
||||||
|
run_cmake(CMP0023-WARN-2)
|
||||||
|
run_cmake(CMP0023-NEW-2)
|
||||||
|
run_cmake(MixedSignature)
|
||||||
|
run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty_vs6_1.cpp)
|
||||||
|
add_library(bar empty_vs6_2.cpp)
|
||||||
|
add_library(bat empty_vs6_3.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(foo LINK_PRIVATE bar)
|
||||||
|
target_link_libraries(foo PRIVATE bat)
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
#include "empty.cpp"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "empty.cpp"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "empty.cpp"
|
Loading…
Reference in New Issue