summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2013-11-04 12:54:20 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2013-11-04 12:54:20 (GMT)
commitb4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16 (patch)
tree85727bbc74ab92f59ab7854d9544e5d2cbbe660c
parenteb3761ae68ea643ee7a2a290f03017e67c888a6b (diff)
parentb51696f003a945e7f9de0b551afd707416cc09fa (diff)
downloadCMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.zip
CMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.tar.gz
CMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.tar.bz2
Merge topic 'policy-CMP0022-fixes-for-master'
b51696f CMP0022: Update target_link_libraries plain signature documentation 25b7f87 Merge branch 'policy-CMP0022-fixes' into policy-CMP0022-fixes-for-master 0a561a0 CMP0022: Warn about a given target at most once 23d21b7 Do not export INTERFACE_LINK_LIBRARIES from non-linkable targets ef10b87 CMP0022: Plain target_link_libraries must populate link interface 0e06788 CMP0022: Add test for target_link_libraries plain signature c0f4a61 CMP0022: Add unit test for null pointer check and message. 4b0cfa7 Merge branch 'output-CMP0022-entries' into policy-CMP0022-fixes
-rw-r--r--Help/command/target_link_libraries.rst17
-rw-r--r--Source/cmExportFileGenerator.cxx5
-rw-r--r--Source/cmTarget.cxx252
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx10
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt7
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.cpp13
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.h14
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.cpp8
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.h7
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib_user.cpp7
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe.cmake7
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake8
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-export-exe.cmake9
-rw-r--r--Tests/RunCMake/CMP0022/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/CMP0022/empty_vs6_4.cpp1
23 files changed, 241 insertions, 161 deletions
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index 41265fd..c2d2dc6 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -32,13 +32,16 @@ per-configuration rules by creating and linking to IMPORTED library
targets. See the IMPORTED mode of the add_library command for more
information.
-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
-INTERFACE_LINK_LIBRARIES target property to override the set of
-transitive link dependencies for a target. Calls to other signatures
-of this command may set the property making any libraries linked
-exclusively by this signature private.
+Library dependencies are transitive by default with this signature.
+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. This transitive "link interface" is stored in the
+INTERFACE_LINK_LIBRARIES target property when policy CMP0022 is set to
+NEW and may be overridden by setting the property directly.
+(When CMP0022 is not set to NEW, transitive linking is builtin but may
+be overridden by the LINK_INTERFACE_LIBRARIES property. Calls to other
+signatures of this command may set the property making any libraries
+linked exclusively by this signature private.)
CMake will also propagate "usage requirements" from linked library
targets. Usage requirements affect compilation of sources in the
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 03e8dff..fdc075e 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -191,6 +191,10 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
{
+ if(!target->IsLinkable())
+ {
+ return false;
+ }
const char *input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
if (input)
{
@@ -654,6 +658,7 @@ cmExportFileGenerator
if (iface->ImplementationIsInterface)
{
+ // Policy CMP0022 must not be NEW.
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LIBRARIES",
iface->Libraries, properties, missingTargets);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f8b6c92..d0390f7 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -81,10 +81,12 @@ class cmTargetInternals
public:
cmTargetInternals()
{
+ this->PolicyWarnedCMP0022 = false;
this->SourceFileFlagsConstructed = false;
}
cmTargetInternals(cmTargetInternals const&)
{
+ this->PolicyWarnedCMP0022 = false;
this->SourceFileFlagsConstructed = false;
}
~cmTargetInternals();
@@ -104,6 +106,7 @@ public:
typedef std::map<TargetConfigPair, OptionalLinkInterface>
LinkInterfaceMapType;
LinkInterfaceMapType LinkInterfaceMap;
+ bool PolicyWarnedCMP0022;
typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
OutputInfoMapType OutputInfoMap;
@@ -685,21 +688,10 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf,
i += this->PrevLinkedLibraries.size();
for( ; i != libs.end(); ++i )
{
- const char *lib = i->first.c_str();
- // We call this so that the dependencies get written to the cache
- this->AddLinkLibrary( mf, selfname, lib, i->second );
-
- if (this->GetType() == cmTarget::STATIC_LIBRARY)
- {
- std::string configLib = this->GetDebugGeneratorExpressions(lib,
- i->second);
- if (cmGeneratorExpression::IsValidTargetName(lib)
- || cmGeneratorExpression::Find(lib) != std::string::npos)
- {
- configLib = "$<LINK_ONLY:" + configLib + ">";
- }
- this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str());
- }
+ // This is equivalent to the target_link_libraries plain signature.
+ this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second );
+ this->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ this->GetDebugGeneratorExpressions(i->first.c_str(), i->second).c_str());
}
this->PrevLinkedLibraries = libs;
}
@@ -5030,12 +5022,20 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
const char* explicitLibraries = 0;
- const char* newExplicitLibraries =
- this->GetProperty("INTERFACE_LINK_LIBRARIES");
std::string linkIfaceProp;
- if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->IsExecutableWithExports())
+ if(this->PolicyStatusCMP0022 != cmPolicies::OLD &&
+ this->PolicyStatusCMP0022 != cmPolicies::WARN)
{
+ // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
+ linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
+ }
+ else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
+ // shared lib or executable.
+
// Lookup the per-configuration property.
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
linkIfaceProp += suffix;
@@ -5047,127 +5047,34 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
}
- if (newExplicitLibraries
- && (!explicitLibraries ||
- (explicitLibraries
- && strcmp(newExplicitLibraries, explicitLibraries) != 0)))
- {
- switch(this->GetPolicyStatusCMP0022())
- {
- case cmPolicies::WARN:
- {
- cmOStringStream w;
- w << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- << "Target \"" << this->GetName() << "\" has a "
- "INTERFACE_LINK_LIBRARIES property which differs from its "
- << linkIfaceProp << " properties."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n "
- << newExplicitLibraries
- << "\n"
- << linkIfaceProp << ":\n "
- << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- }
- // Fall through
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- explicitLibraries = newExplicitLibraries;
- linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- break;
- }
- }
}
- else if(this->GetType() == cmTarget::STATIC_LIBRARY)
+
+ if(explicitLibraries && this->PolicyStatusCMP0022 == cmPolicies::WARN &&
+ !this->Internal->PolicyWarnedCMP0022)
{
- if (newExplicitLibraries)
+ // Compare the explicitly set old link interface properties to the
+ // preferred new link interface property one and warn if different.
+ const char* newExplicitLibraries =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ if (newExplicitLibraries
+ && strcmp(newExplicitLibraries, explicitLibraries) != 0)
{
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
- "INTERFACE_LINK_LIBRARIES", 0, 0);
- std::vector<std::string> ifaceLibs;
- cmSystemTools::ExpandListArgument(
- ge.Parse(newExplicitLibraries)->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), ifaceLibs);
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- headTarget);
- if (ifaceLibs != impl->Libraries)
- {
- switch(this->GetPolicyStatusCMP0022())
- {
- case cmPolicies::WARN:
- {
- std::string oldLibraries;
- std::string newLibraries;
- const char *sep = "";
- for(std::vector<std::string>::const_iterator it
- = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
- {
- oldLibraries += sep;
- oldLibraries += *it;
- sep = ";";
- }
- sep = "";
- for(std::vector<std::string>::const_iterator it
- = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
- {
- newLibraries += sep;
- newLibraries += *it;
- sep = ";";
- }
-
- cmOStringStream w;
- w << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- << "Static library target \"" << this->GetName() << "\" has a "
- "INTERFACE_LINK_LIBRARIES property. This should be preferred "
- "as the source of the link interface for this library. "
- "Ignoring the property and using the link implementation "
- "as the link interface instead."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n "
- << newLibraries
- << "\n"
- << "Link implementation:\n "
- << oldLibraries << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- }
- // Fall through
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- explicitLibraries = newExplicitLibraries;
- linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- break;
- }
- }
- else
- {
- iface.Libraries = impl->Libraries;
- if(this->LinkLanguagePropagatesToDependents())
- {
- // Targets using this archive need its language runtime libraries.
- iface.Languages = impl->Languages;
- }
- }
+ cmOStringStream w;
+ w <<
+ (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property which differs from its " <<
+ linkIfaceProp << " properties."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newExplicitLibraries << "\n" <<
+ linkIfaceProp << ":\n"
+ " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->Internal->PolicyWarnedCMP0022 = true;
}
}
- else if (this->GetType() == cmTarget::INTERFACE_LIBRARY)
- {
- explicitLibraries = newExplicitLibraries;
- linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- }
// There is no implicit link interface for executables or modules
// so if none was explicitly set then there is no link interface.
@@ -5235,11 +5142,12 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
}
}
}
- else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
- || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
- // The implementation shouldn't be the interface if CMP0022 is NEW. That
- // way, the LINK_LIBRARIES property can be set directly without having to
- // empty the INTERFACE_LINK_LIBRARIES
+ else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
+ || this->PolicyStatusCMP0022 == cmPolicies::OLD)
+ // If CMP0022 is NEW then the plain tll signature sets the
+ // INTERFACE_LINK_LIBRARIES, so if we get here then the project
+ // cleared the property explicitly and we should not fall back
+ // to the link implementation.
{
// The link implementation is the default link interface.
LinkImplementation const* impl = this->GetLinkImplementation(config,
@@ -5252,6 +5160,70 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
// Targets using this archive need its language runtime libraries.
iface.Languages = impl->Languages;
}
+
+ if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
+ !this->Internal->PolicyWarnedCMP0022)
+ {
+ // Compare the link implementation fallback link interface to the
+ // preferred new link interface property and warn if different.
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+ "INTERFACE_LINK_LIBRARIES", 0, 0);
+ std::vector<std::string> ifaceLibs;
+ const char* newExplicitLibraries =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ cmSystemTools::ExpandListArgument(
+ ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker),
+ ifaceLibs);
+ if (ifaceLibs != impl->Libraries)
+ {
+ std::string oldLibraries;
+ std::string newLibraries;
+ const char *sep = "";
+ for(std::vector<std::string>::const_iterator it
+ = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
+ {
+ oldLibraries += sep;
+ oldLibraries += *it;
+ sep = ";";
+ }
+ sep = "";
+ for(std::vector<std::string>::const_iterator it
+ = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
+ {
+ newLibraries += sep;
+ newLibraries += *it;
+ sep = ";";
+ }
+ if(oldLibraries.empty())
+ { oldLibraries = "(empty)"; }
+ if(newLibraries.empty())
+ { newLibraries = "(empty)"; }
+
+ cmOStringStream w;
+ w <<
+ (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property. "
+ "This should be preferred as the source of the link interface "
+ "for this library but because CMP0022 is not set CMake is "
+ "ignoring the property and using the link implementation "
+ "as the link interface instead."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newLibraries << "\n"
+ "Link implementation:\n"
+ " " << oldLibraries << "\n";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->Internal->PolicyWarnedCMP0022 = true;
+ }
+ }
}
if(this->GetType() == cmTarget::STATIC_LIBRARY)
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 9add198..c289459 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -390,8 +390,14 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
{
this->Makefile
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
- if (this->CurrentProcessingState != ProcessingKeywordPublicInterface
- && this->CurrentProcessingState != ProcessingPlainPublicInterface)
+ if(this->CurrentProcessingState == ProcessingLinkLibraries)
+ {
+ this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
+ return true;
+ }
+ else if(this->CurrentProcessingState != ProcessingKeywordPublicInterface
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
{
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
index 33757b6..818b8c9 100644
--- a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
@@ -28,3 +28,10 @@ endif()
add_executable(staticlib_exe staticlib_exe.cpp)
target_link_libraries(staticlib_exe staticlib1)
+
+add_library(onlyplainlib1 SHARED onlyplainlib1.cpp)
+add_library(onlyplainlib2 SHARED onlyplainlib2.cpp)
+target_link_libraries(onlyplainlib2 onlyplainlib1)
+
+add_executable(onlyplainlib_user onlyplainlib_user.cpp)
+target_link_libraries(onlyplainlib_user onlyplainlib2)
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.cpp
new file mode 100644
index 0000000..41dc3ce
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.cpp
@@ -0,0 +1,13 @@
+
+#include "onlyplainlib1.h"
+
+OnlyPlainLib1::OnlyPlainLib1()
+ : result(0)
+{
+
+}
+
+int OnlyPlainLib1::GetResult()
+{
+ return result;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.h b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.h
new file mode 100644
index 0000000..c0373ce
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib1.h
@@ -0,0 +1,14 @@
+
+struct
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+OnlyPlainLib1
+{
+ OnlyPlainLib1();
+
+ int GetResult();
+
+private:
+ int result;
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.cpp
new file mode 100644
index 0000000..2865ae9
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.cpp
@@ -0,0 +1,8 @@
+
+#include "onlyplainlib2.h"
+
+OnlyPlainLib1 onlyPlainLib2()
+{
+ OnlyPlainLib1 opl1;
+ return opl1;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.h b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.h
new file mode 100644
index 0000000..74b18a0
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib2.h
@@ -0,0 +1,7 @@
+
+#include "onlyplainlib1.h"
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+OnlyPlainLib1 onlyPlainLib2();
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib_user.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib_user.cpp
new file mode 100644
index 0000000..0fb7b0a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/onlyplainlib_user.cpp
@@ -0,0 +1,7 @@
+
+#include "onlyplainlib2.h"
+
+int main(int argc, char **argv)
+{
+ return onlyPlainLib2().GetResult();
+}
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe.cmake
new file mode 100644
index 0000000..b0268c8
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe.cmake
@@ -0,0 +1,7 @@
+enable_language(CXX)
+
+add_library(testLib empty_vs6_1.cpp)
+add_executable(testExe empty_vs6_2.cpp)
+target_link_libraries(testExe testLib)
+
+export(TARGETS testExe FILE "${CMAKE_CURRENT_BINARY_DIR}/cmp0022NOWARN-exe.cmake")
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake
new file mode 100644
index 0000000..57c3ed0
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake
@@ -0,0 +1,8 @@
+enable_language(CXX)
+
+add_library(foo SHARED empty_vs6_1.cpp)
+add_library(bar SHARED empty_vs6_2.cpp)
+target_link_libraries(bar foo)
+
+add_executable(zot empty.cpp)
+target_link_libraries(zot bar)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
index 6d519f0..6a6a0c7 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
@@ -3,14 +3,16 @@ CMake Warning \(dev\) in CMakeLists.txt:
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
- Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its
- LINK_INTERFACE_LIBRARIES properties.
+ Target "bar" has an INTERFACE_LINK_LIBRARIES property. This should be
+ preferred as the source of the link interface for this library but because
+ CMP0022 is not set CMake is ignoring the property and using the link
+ implementation as the link interface instead.
INTERFACE_LINK_LIBRARIES:
foo
- LINK_INTERFACE_LIBRARIES:
+ Link implementation:
\(empty\)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt
index e41133a..1370c5e 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt
@@ -3,10 +3,10 @@ CMake Warning \(dev\) in CMakeLists.txt:
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
- Static library target "bar" has a INTERFACE_LINK_LIBRARIES property. This
- should be preferred as the source of the link interface for this library.
- Ignoring the property and using the link implementation as the link
- interface instead.
+ Target "bar" has an INTERFACE_LINK_LIBRARIES property. This should be
+ preferred as the source of the link interface for this library but because
+ CMP0022 is not set CMake is ignoring the property and using the link
+ implementation as the link interface instead.
INTERFACE_LINK_LIBRARIES:
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
index 93c0ab3..2f7dfbf 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
@@ -1,10 +1,10 @@
-CMake Warning \(dev\) in CMakeLists.txt:
+^CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
- Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its
- LINK_INTERFACE_LIBRARIES properties.
+ Target "bar" has an INTERFACE_LINK_LIBRARIES property which differs from
+ its LINK_INTERFACE_LIBRARIES properties.
INTERFACE_LINK_LIBRARIES:
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt
index 6370b24..f672285 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt
@@ -3,8 +3,8 @@ CMake Warning \(dev\) in CMakeLists.txt:
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
- Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its
- LINK_INTERFACE_LIBRARIES properties.
+ Target "bar" has an INTERFACE_LINK_LIBRARIES property which differs from
+ its LINK_INTERFACE_LIBRARIES properties.
INTERFACE_LINK_LIBRARIES:
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
index 24b7f45..fe7e858 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
@@ -9,3 +9,8 @@ set_property(TARGET bar PROPERTY LINK_INTERFACE_LIBRARIES bat)
add_library(user empty.cpp)
target_link_libraries(user bar)
+
+# Use "bar" again with a different "head" target to check
+# that the warning does not appear again.
+add_library(user2 empty_vs6_3.cpp)
+target_link_libraries(user2 bar)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe.cmake b/Tests/RunCMake/CMP0022/CMP0022-export-exe.cmake
new file mode 100644
index 0000000..d832fac
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-exe.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+
+cmake_policy(SET CMP0022 NEW)
+
+add_library(testLib empty_vs6_1.cpp)
+add_executable(testExe empty_vs6_2.cpp)
+target_link_libraries(testExe testLib)
+
+export(TARGETS testExe FILE "${CMAKE_CURRENT_BINARY_DIR}/cmp0022NEW-exe.cmake")
diff --git a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
index 8e5824a..2781d20 100644
--- a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
@@ -4,7 +4,10 @@ run_cmake(CMP0022-WARN)
run_cmake(CMP0022-WARN-tll)
run_cmake(CMP0022-WARN-static)
run_cmake(CMP0022-WARN-empty-old)
+run_cmake(CMP0022-NOWARN-exe)
+run_cmake(CMP0022-NOWARN-shared)
run_cmake(CMP0022-NOWARN-static)
run_cmake(CMP0022-NOWARN-static-link_libraries)
run_cmake(CMP0022-export)
+run_cmake(CMP0022-export-exe)
run_cmake(CMP0022-install-export)
diff --git a/Tests/RunCMake/CMP0022/empty_vs6_4.cpp b/Tests/RunCMake/CMP0022/empty_vs6_4.cpp
new file mode 100644
index 0000000..7efedab
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/empty_vs6_4.cpp
@@ -0,0 +1 @@
+#include "empty.cpp"